import { test, expect } from '@playwright/test';

/**
 * Smoke test against the live site.
 * Checks: page loads, no console errors/warnings, no PII exposure, security headers.
 *
 * Run with: npx playwright test e2e/smoke-live-site.spec.ts
 */

const BASE_URL = process.env.SMOKE_BASE_URL || 'https://llmhosts.com';

// PII patterns that should NEVER appear on public pages
const PII_PATTERNS = [
  /brendon/i,
  /brendonurban/i,
  /\b[A-Za-z0-9._%+-]+@gmail\.com\b/,
  /\b[A-Za-z0-9._%+-]+@yahoo\.com\b/,
];

// Pages that don't require auth
const PUBLIC_PAGES = [
  { path: '/', name: 'Landing Page' },
  { path: '/pricing', name: 'Pricing' },
  { path: '/legal/terms', name: 'Terms of Service' },
  { path: '/legal/privacy', name: 'Privacy Policy' },
  { path: '/auth/login', name: 'Login' },
  { path: '/auth/register', name: 'Register' },
  { path: '/auth/forgot-password', name: 'Forgot Password' },
  { path: '/docs', name: 'Docs' },
];

// Dashboard pages (require auth)
const DASHBOARD_PAGES = [
  { path: '/dashboard', name: 'Dashboard' },
  { path: '/dashboard/settings', name: 'Settings' },
  { path: '/dashboard/api-keys', name: 'API Keys' },
  { path: '/dashboard/team', name: 'Team' },
  { path: '/dashboard/tunnel', name: 'Tunnel' },
  { path: '/dashboard/lan-nodes', name: 'LAN Nodes' },
  { path: '/dashboard/topology', name: 'Topology' },
  { path: '/dashboard/cost-analytics', name: 'Cost Analytics' },
  { path: '/dashboard/security', name: 'Security' },
  { path: '/dashboard/cache', name: 'Cache' },
  { path: '/dashboard/router', name: 'Router' },
];

test.describe('Live Site Smoke Tests - Public Pages', () => {
  for (const { path, name } of PUBLIC_PAGES) {
    test(`${name} (${path}) loads without errors`, async ({ page }) => {
      const consoleErrors: string[] = [];
      const consoleWarnings: string[] = [];

      page.on('console', (msg) => {
        if (msg.type() === 'error') consoleErrors.push(msg.text());
        if (msg.type() === 'warning') consoleWarnings.push(msg.text());
      });
      page.on('pageerror', (error) => consoleErrors.push(error.message));

      const response = await page.goto(`${BASE_URL}${path}`, {
        waitUntil: 'networkidle',
        timeout: 30000,
      });

      // Page should load successfully
      expect(response?.status()).toBeLessThan(400);

      // Check for PII in page content
      const bodyText = await page.textContent('body');
      for (const pattern of PII_PATTERNS) {
        expect(bodyText, `PII pattern "${pattern}" found on ${path}`).not.toMatch(pattern);
      }

      // No JS errors allowed
      expect(
        consoleErrors.filter((e) => !e.includes('favicon')),
        `Console errors on ${path}`
      ).toHaveLength(0);

      // Screenshot for visual verification
      await page.screenshot({
        path: `e2e/screenshots/smoke-${name.toLowerCase().replace(/\s+/g, '-')}.png`,
        fullPage: true,
      });
    });
  }
});

test.describe('Security Headers', () => {
  test('frontend responses include required security headers', async ({ request }) => {
    const response = await request.get(`${BASE_URL}/`);
    expect(response.status()).toBeLessThan(400);

    const headers = response.headers();

    expect(headers['x-frame-options'], 'X-Frame-Options').toMatch(/SAMEORIGIN/i);
    expect(headers['x-content-type-options'], 'X-Content-Type-Options').toBe('nosniff');
    expect(headers['referrer-policy'], 'Referrer-Policy').toBe('strict-origin-when-cross-origin');
    expect(headers['strict-transport-security'], 'HSTS').toMatch(/max-age=\d+/);
    expect(headers['content-security-policy'], 'Content-Security-Policy').toBeTruthy();
    expect(headers['permissions-policy'], 'Permissions-Policy').toBeTruthy();
  });

  test('API responses include security headers', async ({ request }) => {
    const response = await request.get(`${BASE_URL.replace('https://', 'https://')}/health`);
    if (response.status() === 200) {
      const headers = response.headers();
      expect(headers['x-content-type-options'], 'X-Content-Type-Options on API').toBe('nosniff');
    }
  });

  test('no sensitive server information is exposed', async ({ request }) => {
    const response = await request.get(`${BASE_URL}/`);
    const headers = response.headers();

    // Server fingerprinting headers should be absent or empty
    expect(headers['server'] || '', 'Server header should be absent or empty').not.toMatch(
      /nginx|apache|iis|express|uvicorn/i
    );
    expect(headers['x-powered-by'] || '', 'X-Powered-By should be absent').toBe('');
  });
});

test.describe('Live Site Smoke Tests - Dashboard (Authenticated)', () => {
  test.beforeEach(async ({ page }) => {
    // Login via the credentials endpoint
    await page.goto(`${BASE_URL}/auth/login`);
    const email = process.env.SEED_USER_EMAIL;
    const password = process.env.SEED_USER_PASSWORD;
    test.skip(!email || !password, 'SEED_USER_EMAIL and SEED_USER_PASSWORD env vars required');
    await page.fill('input[name="email"]', email!);
    await page.fill('input[name="password"]', password!);
    await page.click('button[type="submit"]');

    // Wait for redirect to dashboard
    await page.waitForURL('**/dashboard**', { timeout: 15000 });
  });

  for (const { path, name } of DASHBOARD_PAGES) {
    test(`${name} (${path}) loads without errors`, async ({ page }) => {
      const consoleErrors: string[] = [];

      page.on('console', (msg) => {
        if (msg.type() === 'error') consoleErrors.push(msg.text());
      });
      page.on('pageerror', (error) => consoleErrors.push(error.message));

      await page.goto(`${BASE_URL}${path}`, {
        waitUntil: 'networkidle',
        timeout: 30000,
      });

      // Should not redirect away (means auth worked)
      expect(page.url()).toContain('/dashboard');

      // Dashboard pages show the logged-in user's email in the sidebar — that's expected.
      // PII checks only apply to public pages (checked in the public test suite above).

      // No JS errors
      const realErrors = consoleErrors.filter((e) => !e.includes('favicon'));
      if (realErrors.length > 0) {
        console.log(`Console errors on ${path}:`, JSON.stringify(realErrors, null, 2));
      }
      expect(realErrors, `Console errors on ${path}`).toHaveLength(0);

      await page.screenshot({
        path: `e2e/screenshots/smoke-${name.toLowerCase().replace(/\s+/g, '-')}.png`,
        fullPage: true,
      });
    });
  }
});
