import AxeBuilder from '@axe-core/playwright';
import { expect, type Page } from '@playwright/test';

/**
 * Regras WCAG 2.0/2.1/2.2 nível A e AA (eMAG 3.1 é mapeado no spec `04-acessibilidade-ux.md`).
 * O axe é o árbitro de **contraste** — ele compõe o fundo dos ancestrais (o sniffCSS não).
 */
const WCAG_TAGS = ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22a', 'wcag22aa'];

/** Auditoria axe na página atual, já filtrada para WCAG A/AA. */
export async function analyzeA11y(page: Page) {
  return new AxeBuilder({ page })
    .withTags(WCAG_TAGS)
    // O preview do editor é um `<iframe>` **sandbox** (sem `allow-scripts`, ADR-020): o axe não
    // consegue injetar nele e esperaria para sempre. O conteúdo é o **mesmo** render do portal
    // (ADR-028), coberto pelo axe do portal — então o frame é excluído do scan.
    .exclude('iframe[data-rich-editor-preview]')
    .analyze();
}

/**
 * Falha se houver **qualquer** violação WCAG A/AA (não só `serious`/`critical`),
 * imprimindo um relatório legível — nunca silenciar em massa (plano 11 §5).
 */
export async function expectNoA11yViolations(page: Page): Promise<void> {
  const results = await analyzeA11y(page);

  const report = results.violations
    .map((violation) => {
      const nodes = violation.nodes
        .slice(0, 3)
        .map((node) => `      ${node.target.join(' ')} :: ${node.failureSummary ?? ''}`)
        .join('\n');

      return `  - [${violation.impact ?? 'n/a'}] ${violation.id}: ${violation.help}\n${nodes}\n      ${violation.helpUrl}`;
    })
    .join('\n');

  expect(report, `violações axe em ${page.url()}:\n${report}`).toBe('');
}
