import { test, expect, Page } from '@playwright/test';
import {
  generateTestEmail,
  generateCompanyData,
  generatePhoneNumber,
  generateMockOTP,
  isValidEmail
} from '../helpers/test-helpers';

// Test configuration
const BASE_URL = 'http://localhost:9000';
const TEST_TIMEOUT = 30000;

// Test data generators
function generateTestUser() {
  return {
    fullName: `Test User ${Date.now()}`,
    email: generateTestEmail(),
    password: 'SecurePass123!@#$',
  };
}

// Helper to extract localStorage data
async function getLocalStorageData(page: Page, key: string) {
  return await page.evaluate((k) => localStorage.getItem(k), key);
}

// Helper to check if OTP email was sent (dev mode check)
async function waitForOTPDisplay(page: Page, timeout = 10000) {
  try {
    // In dev mode, OTP is displayed on the page
    const otpDisplay = page.locator('[data-testid="dev-otp-display"]');
    await otpDisplay.waitFor({ timeout, state: 'visible' });
    const otpText = await otpDisplay.textContent();
    const match = otpText?.match(/\d{6}/);
    return match ? match[0] : '123456'; // Fallback to fixed dev OTP
  } catch {
    return '123456'; // Fixed dev OTP
  }
}

// Helper to enter OTP code
async function enterOTP(page: Page, otp: string) {
  const digits = otp.split('');
  for (let i = 0; i < digits.length; i++) {
    await page.fill(`input[data-otp-index="${i}"]`, digits[i]);
  }
}

test.describe('Comprehensive Signup Flow - English', () => {
  test.setTimeout(TEST_TIMEOUT);

  test('Complete flow: Pricing → Signup → OTP → Company → Dashboard', async ({ page }) => {
    const testUser = generateTestUser();
    const companyData = generateCompanyData();

    // STEP 1: Navigate to pricing page
    await page.goto(`${BASE_URL}/en/pricing`);
    await expect(page).toHaveURL(/\/en\/pricing/);

    // Verify pricing page loaded
    await expect(page.locator('h1, h2').first()).toBeVisible();

    // STEP 2: Select a pricing plan (Tier 2 - Professional)
    const tier2Button = page.locator('[data-tier-id="tier2"]').first();
    await tier2Button.waitFor({ state: 'visible', timeout: 5000 });
    await tier2Button.click();

    // Should redirect to signup with plan parameter
    await page.waitForURL(/\/en\/signup/, { timeout: 10000 });

    // STEP 3: Verify localStorage persists selected plan
    const storedPlan = await getLocalStorageData(page, 'selectedPlan');
    console.log('Stored plan in localStorage:', storedPlan);

    // STEP 4: Fill signup form
    await page.fill('input[name="fullName"]', testUser.fullName);
    await page.fill('input[name="email"]', testUser.email);
    await page.fill('input[name="password"]', testUser.password);
    await page.fill('input[name="confirmPassword"]', testUser.password);

    // Submit signup form
    await page.click('button[type="submit"]');

    // STEP 5: Wait for OTP verification page
    await page.waitForURL(/\/en\/signup\/verify/, { timeout: 10000 });

    // Wait for OTP to be displayed (dev mode)
    const otp = await waitForOTPDisplay(page);
    console.log('OTP code:', otp);

    // STEP 6: Enter OTP
    await enterOTP(page, otp);
    await page.click('button[data-testid="verify-button"]');

    // STEP 7: Wait for company info page
    await page.waitForURL(/\/en\/signup\/company-info/, { timeout: 10000 });

    // STEP 8: Fill company information
    await page.fill('input[name="companyName"]', companyData.companyName);
    await page.selectOption('select[name="industry"]', companyData.industry);
    await page.selectOption('select[name="companySize"]', companyData.companySize);
    await page.selectOption('select[name="gccCountry"]', 'uae');
    await page.fill('input[name="phoneNumber"]', companyData.phoneNumber);
    await page.fill('input[name="agentCount"]', '5');

    // Submit company info
    await page.click('button[type="submit"]');

    // STEP 9: Wait for onboarding/success page
    await page.waitForURL(/\/en\/signup\/(onboarding|success)/, { timeout: 10000 });

    // STEP 10: Check if redirected to success or dashboard
    const currentUrl = page.url();
    console.log('Final URL:', currentUrl);

    // Verify success
    expect(currentUrl).toMatch(/\/(success|dashboard|onboarding)/);
  });

  test('Error: Duplicate email registration', async ({ page }) => {
    const testUser = generateTestUser();

    // First registration
    await page.goto(`${BASE_URL}/en/signup`);
    await page.fill('input[name="fullName"]', testUser.fullName);
    await page.fill('input[name="email"]', 'existing@example.com'); // Pre-existing email
    await page.fill('input[name="password"]', testUser.password);
    await page.fill('input[name="confirmPassword"]', testUser.password);

    await page.click('button[type="submit"]');

    // Should show error message
    const errorMessage = page.locator('text=/already exists|already registered/i');
    await expect(errorMessage).toBeVisible({ timeout: 5000 });
  });

  test('Error: Invalid OTP code', async ({ page }) => {
    await page.goto(`${BASE_URL}/en/signup/verify`);

    // Store test email in localStorage
    await page.evaluate(() => {
      localStorage.setItem('signupEmail', 'test@example.com');
    });

    // Reload to apply localStorage
    await page.reload();

    // Enter wrong OTP
    await enterOTP(page, '000000');
    await page.click('button[data-testid="verify-button"]');

    // Should show error
    const errorMessage = page.locator('text=/invalid|incorrect|wrong/i');
    await expect(errorMessage).toBeVisible({ timeout: 5000 });
  });

  test('Error: Expired OTP (10+ minutes)', async ({ page }) => {
    await page.goto(`${BASE_URL}/en/signup/verify`);

    // Store test email with old timestamp
    await page.evaluate(() => {
      localStorage.setItem('signupEmail', 'test@example.com');
      localStorage.setItem('otpSentAt', String(Date.now() - 11 * 60 * 1000)); // 11 minutes ago
    });

    await page.reload();

    // Try to verify
    await enterOTP(page, '123456');
    await page.click('button[data-testid="verify-button"]');

    // Should show expired error
    const errorMessage = page.locator('text=/expired|too old/i');
    await expect(errorMessage).toBeVisible({ timeout: 5000 });
  });

  test('Validation: Weak password rejected', async ({ page }) => {
    await page.goto(`${BASE_URL}/en/signup`);

    await page.fill('input[name="fullName"]', 'Test User');
    await page.fill('input[name="email"]', generateTestEmail());
    await page.fill('input[name="password"]', 'weak'); // Too short, no complexity
    await page.fill('input[name="confirmPassword"]', 'weak');

    await page.click('button[type="submit"]');

    // Should show validation error
    const errorMessage = page.locator('text=/password.*strong|minimum.*12|complexity/i');
    await expect(errorMessage).toBeVisible({ timeout: 5000 });
  });

  test('Validation: Password mismatch rejected', async ({ page }) => {
    await page.goto(`${BASE_URL}/en/signup`);

    await page.fill('input[name="fullName"]', 'Test User');
    await page.fill('input[name="email"]', generateTestEmail());
    await page.fill('input[name="password"]', 'SecurePass123!@#');
    await page.fill('input[name="confirmPassword"]', 'DifferentPass123!@#');

    await page.click('button[type="submit"]');

    // Should show mismatch error
    const errorMessage = page.locator('text=/passwords.*match|passwords.*same/i');
    await expect(errorMessage).toBeVisible({ timeout: 5000 });
  });

  test('Validation: Invalid email format rejected', async ({ page }) => {
    await page.goto(`${BASE_URL}/en/signup`);

    await page.fill('input[name="fullName"]', 'Test User');
    await page.fill('input[name="email"]', 'invalid-email-format');
    await page.fill('input[name="password"]', 'SecurePass123!@#');
    await page.fill('input[name="confirmPassword"]', 'SecurePass123!@#');

    await page.click('button[type="submit"]');

    // Should show email validation error
    const errorMessage = page.locator('text=/valid email|email format/i');
    await expect(errorMessage).toBeVisible({ timeout: 5000 });
  });

  test('Rate limiting: Max OTP attempts (5)', async ({ page }) => {
    await page.goto(`${BASE_URL}/en/signup/verify`);

    await page.evaluate(() => {
      localStorage.setItem('signupEmail', 'test@example.com');
    });
    await page.reload();

    // Try 6 times (exceeding limit of 5)
    for (let i = 0; i < 6; i++) {
      await enterOTP(page, '000000');
      await page.click('button[data-testid="verify-button"]');
      await page.waitForTimeout(500);
    }

    // Should show rate limit error
    const errorMessage = page.locator('text=/too many attempts|rate limit|locked/i');
    await expect(errorMessage).toBeVisible({ timeout: 5000 });
  });

  test('localStorage persistence: Plan selection survives page refresh', async ({ page }) => {
    await page.goto(`${BASE_URL}/en/pricing`);

    // Select plan
    const tier2Button = page.locator('[data-tier-id="tier2"]').first();
    await tier2Button.waitFor({ state: 'visible' });
    await tier2Button.click();

    await page.waitForURL(/\/en\/signup/);

    // Store in localStorage
    await page.evaluate(() => {
      localStorage.setItem('selectedPlan', 'tier2');
      localStorage.setItem('billingPeriod', 'monthly');
      localStorage.setItem('currency', 'USD');
    });

    // Refresh page
    await page.reload();

    // Check data persisted
    const storedPlan = await getLocalStorageData(page, 'selectedPlan');
    const storedBilling = await getLocalStorageData(page, 'billingPeriod');
    const storedCurrency = await getLocalStorageData(page, 'currency');

    expect(storedPlan).toBe('tier2');
    expect(storedBilling).toBe('monthly');
    expect(storedCurrency).toBe('USD');
  });

  test('Company info validation: Required fields enforced', async ({ page }) => {
    await page.goto(`${BASE_URL}/en/signup/company-info`);

    // Try to submit empty form
    await page.click('button[type="submit"]');

    // Should show multiple validation errors
    const errors = page.locator('[role="alert"], .error-message, text=/required/i');
    const errorCount = await errors.count();

    expect(errorCount).toBeGreaterThan(0);
  });

  test('Phone number validation: Format enforced', async ({ page }) => {
    await page.goto(`${BASE_URL}/en/signup/company-info`);

    // Fill required fields
    await page.fill('input[name="companyName"]', 'Test Company');
    await page.selectOption('select[name="industry"]', 'healthcare');
    await page.selectOption('select[name="companySize"]', '1-10');
    await page.selectOption('select[name="gccCountry"]', 'uae');

    // Invalid phone number
    await page.fill('input[name="phoneNumber"]', '123'); // Too short
    await page.fill('input[name="agentCount"]', '3');

    await page.click('button[type="submit"]');

    // Should show phone validation error
    const errorMessage = page.locator('text=/valid phone|phone format/i');
    await expect(errorMessage).toBeVisible({ timeout: 5000 });
  });
});

test.describe('Comprehensive Signup Flow - Arabic (RTL)', () => {
  test.setTimeout(TEST_TIMEOUT);

  test('Complete flow in Arabic: Pricing → Signup → Company', async ({ page }) => {
    const testUser = generateTestUser();
    const companyData = generateCompanyData();

    // STEP 1: Navigate to Arabic pricing page
    await page.goto(`${BASE_URL}/ar/pricing`);
    await expect(page).toHaveURL(/\/ar\/pricing/);

    // Verify RTL layout
    const mainElement = page.locator('main');
    const dir = await mainElement.getAttribute('dir');
    expect(dir).toBe('rtl');

    // STEP 2: Select plan
    const tier2Button = page.locator('[data-tier-id="tier2"]').first();
    await tier2Button.waitFor({ state: 'visible' });
    await tier2Button.click();

    await page.waitForURL(/\/ar\/signup/);

    // STEP 3: Fill signup form
    await page.fill('input[name="fullName"]', testUser.fullName);
    await page.fill('input[name="email"]', testUser.email);
    await page.fill('input[name="password"]', testUser.password);
    await page.fill('input[name="confirmPassword"]', testUser.password);

    await page.click('button[type="submit"]');

    // STEP 4: Wait for OTP page
    await page.waitForURL(/\/ar\/signup\/verify/, { timeout: 10000 });

    // Verify RTL maintained
    const verifyDir = await page.locator('main').getAttribute('dir');
    expect(verifyDir).toBe('rtl');
  });

  test('RTL layout verification on all signup pages', async ({ page }) => {
    const pages = [
      '/ar/signup',
      '/ar/signup/verify',
      '/ar/signup/company-info',
    ];

    for (const pagePath of pages) {
      await page.goto(`${BASE_URL}${pagePath}`);

      // Store dummy data for navigation
      await page.evaluate(() => {
        localStorage.setItem('signupEmail', 'test@example.com');
      });
      await page.reload();

      // Check RTL
      const dir = await page.locator('main').getAttribute('dir');
      expect(dir).toBe('rtl');
      console.log(`✓ ${pagePath} has RTL layout`);
    }
  });
});

test.describe('Data Persistence Tests', () => {
  test('Signup data persists in localStorage', async ({ page }) => {
    await page.goto(`${BASE_URL}/en/signup`);

    // Fill form but don't submit
    const testUser = generateTestUser();
    await page.fill('input[name="email"]', testUser.email);
    await page.fill('input[name="fullName"]', testUser.fullName);

    // Manually store in localStorage
    await page.evaluate((data) => {
      localStorage.setItem('signupData', JSON.stringify(data));
    }, { email: testUser.email, fullName: testUser.fullName });

    // Navigate away and back
    await page.goto(`${BASE_URL}/en/pricing`);
    await page.goto(`${BASE_URL}/en/signup`);

    // Check if data persisted
    const storedData = await page.evaluate(() => {
      return localStorage.getItem('signupData');
    });

    expect(storedData).toBeTruthy();
    const parsedData = JSON.parse(storedData!);
    expect(parsedData.email).toBe(testUser.email);
  });

  test('Company info persists across page refresh', async ({ page }) => {
    await page.goto(`${BASE_URL}/en/signup/company-info`);

    const companyData = generateCompanyData();

    // Fill form
    await page.fill('input[name="companyName"]', companyData.companyName);

    // Store in localStorage
    await page.evaluate((data) => {
      localStorage.setItem('companyInfo', JSON.stringify(data));
    }, companyData);

    // Refresh
    await page.reload();

    // Check persistence
    const storedData = await page.evaluate(() => {
      return localStorage.getItem('companyInfo');
    });

    expect(storedData).toBeTruthy();
    const parsedData = JSON.parse(storedData!);
    expect(parsedData.companyName).toBe(companyData.companyName);
  });
});

test.describe('Mobile Responsive Tests', () => {
  test('Signup flow works on mobile viewport', async ({ page }) => {
    // Set iPhone 12 viewport
    await page.setViewportSize({ width: 390, height: 844 });

    await page.goto(`${BASE_URL}/en/pricing`);

    // Select plan on mobile
    const tier2Button = page.locator('[data-tier-id="tier2"]').first();
    await tier2Button.scrollIntoViewIfNeeded();
    await tier2Button.click();

    await page.waitForURL(/\/en\/signup/);

    // Fill form on mobile
    const testUser = generateTestUser();
    await page.fill('input[name="fullName"]', testUser.fullName);
    await page.fill('input[name="email"]', testUser.email);
    await page.fill('input[name="password"]', testUser.password);
    await page.fill('input[name="confirmPassword"]', testUser.password);

    // Verify form is usable on mobile
    const submitButton = page.locator('button[type="submit"]');
    await expect(submitButton).toBeVisible();
    await expect(submitButton).toBeEnabled();
  });
});

test.describe('Security Tests', () => {
  test('CSRF token validation', async ({ page }) => {
    // Navigate to signup
    await page.goto(`${BASE_URL}/en/signup`);

    // Try to submit without CSRF token (intercept and remove)
    await page.route('**/api/register', async (route) => {
      const request = route.request();
      const headers = { ...request.headers() };
      delete headers['x-csrf-token'];

      await route.continue({ headers });
    });

    const testUser = generateTestUser();
    await page.fill('input[name="fullName"]', testUser.fullName);
    await page.fill('input[name="email"]', testUser.email);
    await page.fill('input[name="password"]', testUser.password);
    await page.fill('input[name="confirmPassword"]', testUser.password);

    await page.click('button[type="submit"]');

    // Should show CSRF error
    const errorMessage = page.locator('text=/csrf|forbidden|unauthorized/i');
    await expect(errorMessage).toBeVisible({ timeout: 5000 });
  });

  test('XSS prevention in input fields', async ({ page }) => {
    await page.goto(`${BASE_URL}/en/signup`);

    // Try to inject script
    const xssPayload = '<script>alert("XSS")</script>';
    await page.fill('input[name="fullName"]', xssPayload);

    // Check that script is sanitized
    const inputValue = await page.inputValue('input[name="fullName"]');
    expect(inputValue).not.toContain('<script>');
  });
});
