/**
 * Auth Pages Mobile Tests
 *
 * Tests for authentication pages (login/register/change-password) on mobile devices.
 * Login and Register are tested WITHOUT authentication to verify unauthenticated
 * user experience. Change-password requires authentication.
 *
 * Pages tested:
 * 1. /auth/login - Login page (unauthenticated)
 * 2. /auth/register - Registration page (unauthenticated)
 * 3. /auth/change-password - Change password page (authenticated)
 */

import { test, expect } from '@playwright/test';
const {
  MIN_TOUCH_TARGET,
} = require('./helpers/mobile-utils');

// Auth pages configuration
const AUTH_PAGES = [
  { path: '/auth/login', name: 'Login' },
  { path: '/auth/register', name: 'Register' },
];

// ============================================
// AUTH PAGES - UNAUTHENTICATED TESTS
// ============================================

test.describe('Auth Pages Mobile', () => {
  // Clear authentication state for these tests
  test.use({ storageState: { cookies: [], origins: [] } });

  // ============================================
  // NO HORIZONTAL OVERFLOW TESTS
  // ============================================

  test.describe('No Horizontal Overflow', () => {
    for (const pageInfo of AUTH_PAGES) {
      test(`${pageInfo.name} - no horizontal overflow`, async ({ page }) => {
        await page.goto(pageInfo.path);
        await page.waitForLoadState('domcontentloaded');

        const hasOverflow = await page.evaluate(() =>
          document.documentElement.scrollWidth > window.innerWidth
        );

        if (hasOverflow) {
          const overflowInfo = await page.evaluate(() => {
            const elements = [];
            document.querySelectorAll('*').forEach((el) => {
              const rect = el.getBoundingClientRect();
              if (rect.right > window.innerWidth) {
                elements.push({
                  tag: el.tagName.toLowerCase(),
                  class: el.className,
                  id: el.id,
                  width: Math.round(rect.width),
                  right: Math.round(rect.right),
                  overflow: Math.round(rect.right - window.innerWidth),
                });
              }
            });
            return elements.slice(0, 5);
          });
          console.log('Overflowing elements:', JSON.stringify(overflowInfo, null, 2));
        }

        expect(hasOverflow, `${pageInfo.name} should have no horizontal overflow`).toBe(false);
      });
    }
  });

  // ============================================
  // FORM TOUCH TARGET TESTS
  // ============================================

  test.describe('Form Touch Targets', () => {
    for (const pageInfo of AUTH_PAGES) {
      test(`${pageInfo.name} - form inputs meet touch target requirements`, async ({ page, isMobile }, testInfo) => {
        if (!isMobile) {
          test.skip();
          return;
        }

        // Skip on tablets - different touch target requirements
        const isTablet = testInfo.project.name.includes('iPad');
        if (isTablet) {
          test.skip();
          return;
        }

        await page.goto(pageInfo.path);
        await page.waitForLoadState('domcontentloaded');

        // Check form inputs have adequate height
        const inputs = page.locator('input[type="text"], input[type="password"], input[type="email"]');
        const inputCount = await inputs.count();

        for (let i = 0; i < inputCount; i++) {
          const input = inputs.nth(i);
          const box = await input.boundingBox();

          expect(box).toBeTruthy();
          expect(
            box.height,
            `Input ${i + 1} on ${pageInfo.name} should have height >= ${MIN_TOUCH_TARGET}px`
          ).toBeGreaterThanOrEqual(MIN_TOUCH_TARGET);
        }
      });

      test(`${pageInfo.name} - submit button meets touch target requirements`, async ({ page, isMobile }, testInfo) => {
        if (!isMobile) {
          test.skip();
          return;
        }

        const isTablet = testInfo.project.name.includes('iPad');
        if (isTablet) {
          test.skip();
          return;
        }

        await page.goto(pageInfo.path);
        await page.waitForLoadState('domcontentloaded');

        const submitButton = page.locator('button[type="submit"]');
        await expect(submitButton).toBeVisible();

        const box = await submitButton.boundingBox();
        expect(box).toBeTruthy();
        expect(box.height, `Submit button should have height >= ${MIN_TOUCH_TARGET}px`).toBeGreaterThanOrEqual(MIN_TOUCH_TARGET);
      });
    }
  });

  // ============================================
  // PAGE LOADS WITHOUT ERRORS
  // ============================================

  test.describe('Basic Load Tests', () => {
    for (const pageInfo of AUTH_PAGES) {
      test(`${pageInfo.name} - loads without errors`, async ({ page }) => {
        const errors = [];
        page.on('console', (msg) => {
          if (msg.type() === 'error') {
            errors.push(msg.text());
          }
        });

        const pageErrors = [];
        page.on('pageerror', (error) => {
          pageErrors.push(error.message);
        });

        await page.goto(pageInfo.path);
        await page.waitForLoadState('domcontentloaded');

        const criticalErrors = errors.filter(
          (err) =>
            !err.includes('favicon') &&
            !err.includes('404') &&
            !err.includes('Failed to load resource')
        );

        expect(pageErrors.length, `${pageInfo.name} should have no page errors`).toBe(0);
        expect(
          criticalErrors.length,
          `${pageInfo.name} should have no critical console errors: ${criticalErrors.join(', ')}`
        ).toBe(0);
      });
    }
  });

  // ============================================
  // PAGE-SPECIFIC CONTENT TESTS
  // ============================================

  test.describe('Login Page Content', () => {
    test('displays login form correctly', async ({ page }) => {
      await page.goto('/auth/login');
      await page.waitForLoadState('domcontentloaded');

      // Check for page title/header
      await expect(page.locator('h1')).toContainText(/Local Deep Research|Login/i);

      // Check for form elements
      await expect(page.locator('input[name="username"]')).toBeVisible();
      await expect(page.locator('input[name="password"]')).toBeVisible();
      await expect(page.locator('button[type="submit"]')).toBeVisible();

      // Check for encryption banner
      const encryptionBanner = page.locator('.ldr-encryption-banner');
      if (await encryptionBanner.count() > 0) {
        await expect(encryptionBanner).toBeVisible();
      }
    });

    test('remember me checkbox is accessible', async ({ page, isMobile }, testInfo) => {
      if (!isMobile) {
        test.skip();
        return;
      }

      const isTablet = testInfo.project.name.includes('iPad');
      if (isTablet) {
        test.skip();
        return;
      }

      await page.goto('/auth/login');
      await page.waitForLoadState('domcontentloaded');

      const rememberCheckbox = page.locator('input[name="remember"]');
      if (await rememberCheckbox.count() > 0) {
        await expect(rememberCheckbox).toBeVisible();

        // Check the label is clickable
        const label = page.locator('.ldr-checkbox-label').first();
        await expect(label).toBeVisible();
      }
    });
  });

  test.describe('Register Page Content', () => {
    test('displays registration form correctly', async ({ page }) => {
      await page.goto('/auth/register');
      await page.waitForLoadState('domcontentloaded');

      // Check for page header
      await expect(page.locator('h1')).toContainText(/Create Account|Register/i);

      // Check for form elements
      await expect(page.locator('input[name="username"]')).toBeVisible();
      await expect(page.locator('input[name="password"]')).toBeVisible();
      await expect(page.locator('input[name="confirm_password"]')).toBeVisible();
      await expect(page.locator('button[type="submit"]')).toBeVisible();

      // Check for acknowledgement checkbox
      const acknowledgeCheckbox = page.locator('input[name="acknowledge"]');
      await expect(acknowledgeCheckbox).toBeVisible();
    });

    test('password requirements section is visible', async ({ page }) => {
      await page.goto('/auth/register');
      await page.waitForLoadState('domcontentloaded');

      const passwordRequirements = page.locator('.ldr-password-requirements');
      if (await passwordRequirements.count() > 0) {
        await expect(passwordRequirements).toBeVisible();
      }
    });

    test('acknowledgement checkbox is accessible on mobile', async ({ page, isMobile }, testInfo) => {
      if (!isMobile) {
        test.skip();
        return;
      }

      const isTablet = testInfo.project.name.includes('iPad');
      if (isTablet) {
        test.skip();
        return;
      }

      await page.goto('/auth/register');
      await page.waitForLoadState('domcontentloaded');

      const acknowledgeBox = page.locator('.ldr-acknowledge-box');
      if (await acknowledgeBox.count() > 0) {
        await expect(acknowledgeBox).toBeVisible();

        // Check checkbox is interactable
        const checkbox = acknowledgeBox.locator('input[type="checkbox"]');
        await expect(checkbox).toBeVisible();
      }
    });
  });

  // ============================================
  // NAVIGATION BETWEEN AUTH PAGES
  // ============================================

  test.describe('Auth Page Navigation', () => {
    test('can navigate from login to register', async ({ page }) => {
      await page.goto('/auth/login');
      await page.waitForLoadState('domcontentloaded');

      // Use specific selector and DOM-level click for consistency with the
      // register→login test.  The login page is borderline for the Desktop
      // Safari 720px viewport, so the same WebKit scroll+click issue can
      // appear here as well.
      const registerLink = page.locator('.ldr-auth-links a[href*="register"]');
      await expect(registerLink).toBeVisible();
      await registerLink.scrollIntoViewIfNeeded();
      await registerLink.evaluate(node => node.click());
      await page.waitForURL('**/auth/register**', { timeout: 15000 });

      expect(page.url()).toContain('/auth/register');
    });

    test('can navigate from register to login', async ({ page }) => {
      await page.goto('/auth/register');
      await page.waitForLoadState('domcontentloaded');

      // Use specific selector to target the link in the auth-links section.
      // The register page is tall (many form fields) inside a flex-centered
      // body.  In WebKit, Playwright's coordinated scroll-then-click can fail
      // to trigger navigation, so we dispatch a DOM-level click instead.
      const loginLink = page.locator('.ldr-auth-links a[href*="login"]');
      await expect(loginLink).toBeVisible();
      await loginLink.scrollIntoViewIfNeeded();
      await loginLink.evaluate(node => node.click());
      await page.waitForURL('**/auth/login**', { timeout: 15000 });

      expect(page.url()).toContain('/auth/login');
    });
  });

  // ============================================
  // RESPONSIVE AT EXTRA SMALL WIDTHS (iPhone SE)
  // ============================================

  test.describe('Responsive at Extra Small Widths', () => {
    for (const pageInfo of AUTH_PAGES) {
      test(`${pageInfo.name} - responsive on iPhone SE width (375px)`, async ({ page, isMobile }, testInfo) => {
        if (!isMobile) {
          test.skip();
          return;
        }

        // Only run on iPhone SE project (smallest viewport)
        if (!testInfo.project.name.includes('iPhone SE')) {
          test.skip();
          return;
        }

        await page.goto(pageInfo.path);
        await page.waitForLoadState('domcontentloaded');

        // Check no horizontal overflow
        const hasOverflow = await page.evaluate(() =>
          document.documentElement.scrollWidth > window.innerWidth
        );
        expect(hasOverflow, `${pageInfo.name} should not overflow on 375px width`).toBe(false);

        // Check form container is within viewport
        const container = page.locator('.ldr-auth-container, .ldr-card').first();
        const box = await container.boundingBox();
        expect(box).toBeTruthy();
        expect(box.width, `Container should be <= viewport width`).toBeLessThanOrEqual(375);
      });
    }
  });

});

// NOTE: /auth/change-password returns a server error in the test environment
// (the route requires specific database encryption support). Tests for this
// page are skipped until the server-side issue is resolved.
