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

/** Origem do app (ADR-002: nenhuma requisição deve sair daqui por padrão). */
export const APP_ORIGIN = new URL(process.env.BASE_URL ?? 'http://localhost:8080').origin;

/**
 * Contrato estrutural do shell do portal (ADR-016): a estrutura é da **estrutura**,
 * não do módulo. Toda tela pública precisa apresentá-la.
 */
export type KeyPage = {
  readonly name: string;
  readonly path: string;
  readonly status: number;
};

/** Telas-chave do portal cobertas pelo gate (ADR-025). */
export const KEY_PAGES: readonly KeyPage[] = [
  { name: 'home', path: '/', status: 200 },
  { name: 'noticias', path: '/noticias', status: 200 },
  { name: 'nao-encontrado', path: '/pagina-inexistente-e2e', status: 404 },
];

/** Navega e **exige** o status HTTP esperado (nunca seguir com uma página de erro). */
export async function gotoExpecting(
  page: Page,
  path: string,
  status: number,
): Promise<Response> {
  const response = await page.goto(path);

  expect(response, `sem resposta HTTP para ${path}`).not.toBeNull();
  expect(response?.status(), `status de ${path}`).toBe(status);

  return response as Response;
}

/** Estrutura universal do shell: landmarks, skip links, um único `<h1>` e foco no conteúdo. */
export async function expectPortalChrome(page: Page): Promise<void> {
  await expect(page.locator('html')).toHaveAttribute('lang', 'pt-BR');

  const skipLinks = page.locator('nav.skip-links a');
  expect(await skipLinks.count()).toBeGreaterThanOrEqual(3);
  await expect(page.getByRole('link', { name: 'Ir para o conteúdo' })).toBeAttached();

  await expect(page.locator('header.site-header')).toBeVisible();
  await expect(page.locator('main#main-content')).toBeVisible();
  await expect(page.locator('main#main-content')).toHaveAttribute('tabindex', '-1');
  await expect(page.locator('footer#site-footer')).toBeVisible();

  expect(await page.locator('h1').count(), 'exatamente um <h1> por página').toBe(1);
}

/** Coleta requisições que **saem** da origem do app (esperado: nenhuma — ADR-002). */
export function trackExternalRequests(page: Page): string[] {
  const external: string[] = [];

  page.on('request', (request) => {
    let origin: string;

    try {
      origin = new URL(request.url()).origin;
    } catch {
      external.push(request.url());

      return;
    }

    if (origin !== APP_ORIGIN) {
      external.push(request.url());
    }
  });

  return external;
}
