import { test, expect, type ConsoleMessage } from '@playwright/test';
import { ROUTES } from './helpers';

for (const route of ROUTES) {
  test(`${route} renders, has h1, no console errors`, async ({ page }) => {
    const errors: string[] = [];
    // Ignore third-party noise from the author-deploy analytics/ads stack
    // (GA + AdSense), which 403/CSP-warn under a real Chrome but never under
    // the bundled headless browser. None of it is the template's own code.
    const THIRD_PARTY = /googlesyndication|google-analytics|googletagmanager|doubleclick|adsbygoogle|gtag|pagead|google\.com|content security policy|frame-ancestors|report-only/i;
    const isThirdParty = (m: ConsoleMessage) =>
      THIRD_PARTY.test(m.text()) ||
      THIRD_PARTY.test(m.location()?.url ?? '') ||
      /failed to load resource/i.test(m.text());
    page.on('pageerror', (e) => errors.push(`pageerror: ${e.message}`));
    page.on('console', (m: ConsoleMessage) => {
      if (m.type() === 'error' && !isThirdParty(m)) errors.push(`console.error: ${m.text()}`);
    });

    const res = await page.goto(route);
    expect(res, `no response for ${route}`).not.toBeNull();
    expect(res!.status(), `status for ${route}`).toBe(200);
    await expect(page.locator('h1').first()).toBeVisible();
    expect(errors, `console errors on ${route}:\n${errors.join('\n')}`).toEqual([]);
  });
}

test('home meta description is set', async ({ page }) => {
  await page.goto('/');
  const meta = await page.locator('meta[name="description"]').getAttribute('content');
  expect(meta).toBeTruthy();
  expect(meta!.length).toBeGreaterThan(20);
});

test('home emits Person JSON-LD with required fields', async ({ page }) => {
  await page.goto('/');
  const script = await page.locator('script[type="application/ld+json"]').textContent();
  expect(script).toBeTruthy();
  const data = JSON.parse(script!);
  expect(data['@type']).toBe('Person');
  expect(data.name).toBe('Nadia Costa');
  expect(data.jobTitle).toBe('Senior Software Engineer');
  expect(data.email).toContain('mailto:');
  expect(Array.isArray(data.sameAs)).toBe(true);
  expect(data.sameAs.length).toBeGreaterThanOrEqual(2);
  expect(Array.isArray(data.alumniOf)).toBe(true);
  expect(data.alumniOf.length).toBe(2);
  expect(Array.isArray(data.knowsAbout)).toBe(true);
  expect(data.worksFor['@type']).toBe('Organization');
});

test('OG image absolute and 1200×630', async ({ page }) => {
  await page.goto('/');
  const og = await page.locator('meta[property="og:image"]').getAttribute('content');
  expect(og).toMatch(/^https?:\/\//);
  expect(og).toContain('og-image.png');
  expect(await page.locator('meta[property="og:image:width"]').getAttribute('content')).toBe('1200');
  expect(await page.locator('meta[property="og:image:height"]').getAttribute('content')).toBe('630');
});

test('OG type is "profile"', async ({ page }) => {
  await page.goto('/');
  expect(await page.locator('meta[property="og:type"]').getAttribute('content')).toBe('profile');
});

test('Twitter card is summary_large_image', async ({ page }) => {
  await page.goto('/');
  expect(await page.locator('meta[name="twitter:card"]').getAttribute('content')).toBe('summary_large_image');
});

test('canonical link is absolute', async ({ page }) => {
  await page.goto('/');
  const canonical = await page.locator('link[rel="canonical"]').getAttribute('href');
  expect(canonical).toMatch(/^https?:\/\//);
});

test('sitemap.xml is reachable', async ({ page }) => {
  const res = await page.goto('/sitemap-index.xml');
  expect(res?.status()).toBe(200);
});

test('robots.txt is reachable', async ({ page }) => {
  const res = await page.goto('/robots.txt');
  expect(res?.status()).toBe(200);
});
