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

/**
 * E2E Smoke Test Suite (P0)
 * Critical tests that must pass before any deployment
 * Should run in under 2 minutes
 */

test.describe('Smoke Suite - Critical Page Loads', () => {
  const criticalPages = [
    { path: '/', name: 'Homepage' },
    { path: '/about', name: 'About' },
    { path: '/services', name: 'Services' },
    { path: '/portfolio', name: 'Portfolio' },
    { path: '/blog', name: 'Blog Listing' },
    { path: '/blog/getting-started-with-astro', name: 'Blog Post' },
    { path: '/contact', name: 'Contact' },
    { path: '/privacy', name: 'Privacy Policy' },
    { path: '/terms', name: 'Terms of Service' }
  ];

  for (const page of criticalPages) {
    test(`${page.name} loads successfully`, async ({ page: browserPage }) => {
      const response = await browserPage.goto(page.path);

      // Page should return 200
      expect(response?.status()).toBe(200);

      // Core layout elements must be present
      await expect(browserPage.locator('header')).toBeVisible();
      await expect(browserPage.locator('main')).toBeVisible();
      await expect(browserPage.locator('footer')).toBeVisible();

      // Title should be set
      const title = await browserPage.title();
      expect(title.length).toBeGreaterThan(0);
    });
  }
});

test.describe('Smoke Suite - Critical User Flows', () => {
  test('homepage to contact flow works', async ({ page }) => {
    await page.goto('/');

    const contactLink = page.locator('a[href="/contact"]').first();
    await contactLink.click();

    await expect(page).toHaveURL('/contact');
    await expect(page.locator('#contact-form')).toBeVisible();
  });

  test('navigation menu works', async ({ page }) => {
    await page.goto('/');

    // Test main navigation links
    const navLinks = ['About', 'Services', 'Blog'];

    for (const linkText of navLinks) {
      await page.goto('/');
      const link = page.locator(`a:has-text("${linkText}")`).first();

      if (await link.isVisible()) {
        await link.click();
        await page.waitForLoadState('domcontentloaded');

        // Should navigate away from homepage (URL should contain the linked path)
        expect(page.url()).not.toMatch(/http:\/\/localhost:10000\/?$/);
      }
    }
  });

  test('contact form submission works', async ({ page }) => {
    await page.goto('/contact');

    await page.locator('input[name="name"]').fill('Smoke Test User');
    await page.locator('#contact-form input[name="email"]').fill('smoke@test.com');
    await page.locator('select[name="subject"]').selectOption('web-development');
    await page.locator('textarea[name="message"]').fill('Automated smoke test message.');

    await page.locator('#contact-form button[type="submit"]').click();

    // Should show success state or an error toast (rate limit / server error both indicate API was reached)
    // Wait for either success state or a toast alert to become visible
    await page.waitForFunction(() => {
      const successState = document.getElementById('success-state');
      const toastAlert = document.querySelector('#toast-container [role="alert"]');
      const successVisible = successState && !successState.classList.contains('hidden');
      const toastVisible = toastAlert && (toastAlert as HTMLElement).offsetParent !== null;
      return successVisible || toastVisible;
    }, { timeout: 10000 });
  });

  test('blog navigation works', async ({ page }) => {
    await page.goto('/blog');

    const posts = page.locator('article, [class*="post"]');
    expect(await posts.count()).toBeGreaterThan(0);

    // Click first post
    await posts.first().locator('a').first().click();
    await expect(page).toHaveURL(/\/blog\//);

    // Content should load
    await expect(page.locator('h1')).toBeVisible();
  });
});

test.describe('Smoke Suite - Performance', () => {
  test('homepage loads within acceptable time', async ({ page }) => {
    const startTime = Date.now();

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

    const loadTime = Date.now() - startTime;

    // Should load in under 3 seconds (generous for smoke test)
    expect(loadTime).toBeLessThan(3000);
  });

  test('no JavaScript errors on homepage', async ({ page }) => {
    const errors: string[] = [];

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

    await page.goto('/');
    await page.waitForLoadState('networkidle');

    // Should have no console errors
    expect(errors.length).toBe(0);
  });
});

test.describe('Smoke Suite - Responsiveness', () => {
  const viewports = [
    { width: 375, height: 667, name: 'Mobile' },
    { width: 768, height: 1024, name: 'Tablet' },
    { width: 1920, height: 1080, name: 'Desktop' }
  ];

  for (const viewport of viewports) {
    test(`homepage renders correctly on ${viewport.name}`, async ({ page }) => {
      await page.setViewportSize({ width: viewport.width, height: viewport.height });
      await page.goto('/');

      // Layout should not overflow
      const bodyWidth = await page.evaluate(() => document.body.scrollWidth);
      expect(bodyWidth).toBeLessThanOrEqual(viewport.width + 20);

      // Core elements visible
      await expect(page.locator('header')).toBeVisible();
      await expect(page.locator('main')).toBeVisible();
    });
  }
});

test.describe('Smoke Suite - SEO Basics', () => {
  test('homepage has proper meta tags', async ({ page }) => {
    await page.goto('/');

    // Title
    const title = await page.title();
    expect(title.length).toBeGreaterThan(0);
    expect(title.length).toBeLessThan(60);

    // Meta description
    const description = await page.locator('meta[name="description"]').getAttribute('content');
    expect(description).toBeTruthy();
    expect(description!.length).toBeGreaterThan(50);

    // Open Graph
    const ogTitle = await page.locator('meta[property="og:title"]').getAttribute('content');
    expect(ogTitle).toBeTruthy();
  });

  test('blog post has proper structured data', async ({ page }) => {
    await page.goto('/blog/getting-started-with-astro');

    // Check for JSON-LD structured data
    const jsonLd = page.locator('script[type="application/ld+json"]');
    const count = await jsonLd.count();

    if (count > 0) {
      const content = await jsonLd.first().textContent();
      expect(content).toBeTruthy();

      // Should be valid JSON
      const parsed = JSON.parse(content!);
      expect(parsed).toBeTruthy();
    }
  });
});

test.describe('Smoke Suite - Security Headers', () => {
  test('security headers are present', async ({ page }) => {
    const response = await page.goto('/');

    if (response) {
      const headers = response.headers();

      // Check for basic security headers
      // Note: Some headers may only be present in production
      const hasCSP = 'content-security-policy' in headers;
      const hasXFrame = 'x-frame-options' in headers;

      // At least one should be present
      expect(hasCSP || hasXFrame).toBeTruthy();
    }
  });

  test('HTTPS redirect configured (production only)', async ({ page }) => {
    const response = await page.goto('/');

    if (response) {
      const url = response.url();

      // In production, should use HTTPS
      // In dev mode (localhost), HTTP is acceptable
      expect(url.startsWith('http://localhost') || url.startsWith('https://')).toBeTruthy();
    }
  });
});

test.describe('Smoke Suite - Accessibility Basics', () => {
  test('homepage has no major accessibility violations', async ({ page }) => {
    await page.goto('/');

    // Check for basic accessibility requirements
    // 1. Images have alt text
    const images = page.locator('img');
    const imageCount = await images.count();

    for (let i = 0; i < Math.min(imageCount, 5); i++) {
      const img = images.nth(i);
      if (await img.isVisible()) {
        const alt = await img.getAttribute('alt');
        expect(alt !== null).toBeTruthy();
      }
    }

    // 2. Links have text or aria-label
    const links = page.locator('a');
    const linkCount = await links.count();

    for (let i = 0; i < Math.min(linkCount, 10); i++) {
      const link = links.nth(i);
      const text = await link.textContent();
      const ariaLabel = await link.getAttribute('aria-label');

      expect((text && text.trim().length > 0) || ariaLabel).toBeTruthy();
    }
  });

  test('contact form is keyboard navigable', async ({ page }) => {
    await page.goto('/contact');

    // Click on the name field directly to set focus, then tab to email
    const firstField = page.locator('input[name="name"]');
    await firstField.click();
    await expect(firstField).toBeFocused();

    await page.keyboard.press('Tab');
    const secondField = page.locator('#contact-form input[name="email"]');
    await expect(secondField).toBeFocused();
  });
});

test.describe('Smoke Suite - Critical Assets', () => {
  test('favicon loads', async ({ page }) => {
    await page.goto('/');

    const favicon = page.locator('link[rel="icon"], link[rel="shortcut icon"]');
    const count = await favicon.count();

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

  test('main stylesheet loads', async ({ page }) => {
    const response = await page.goto('/');

    await page.waitForLoadState('networkidle');

    // Check that some CSS is applied
    const bgColor = await page.locator('body').evaluate(el => {
      return window.getComputedStyle(el).backgroundColor;
    });

    expect(bgColor).toBeTruthy();
  });
});
