import { defineConfig, devices } from '@playwright/test';

/**
 * Configuração E2E (plano 11 §3, ADR-025).
 *
 * - `BASE_URL` parametriza o ambiente (default `http://localhost:50700` — o app roteia por Host
 *   `localhost`; `127.0.0.1` devolve 404).
 * - **Paralelismo por arquivo** (`E2E_WORKERS`, default 4) e `retries: 0`: as specs são
 *   independentes entre arquivos (cada uma cria seus dados com nomes únicos); dentro de um arquivo
 *   a ordem é preservada (`fullyParallel: false`). Medido: 100 testes em ~75 s (era ~174 s com 1
 *   worker). `--fully-parallel` **quebra** o lote da galeria (dois testes mutam o mesmo catálogo) —
 *   por isso ele fica desligado: isolamento por arquivo é o contrato de determinismo (ADR-001).
 * - O lote **`cms-serial`** muta estado **global** (tema/menu/shell, ativação de módulo, a home
 *   publicada e um perfil de layout). Ele roda com **um** worker e **todos** os outros projetos
 *   declaram `dependencies: ['cms-serial']`: o estado é mutado/restaurado antes de qualquer outra
 *   spec começar, então nenhum projeto observa a janela intermediária.
 * - Seis projetos: desktop, mobile (pointer coarse → alvos de toque), **sem JavaScript** (ADR-010),
 *   painel no **domínio próprio** (`cms.<host>` — ADR-005/037), painel mobile e o lote serial.
 */
const baseURL = process.env.BASE_URL ?? 'http://localhost:50700';

/**
 * O CMS vive no **domínio próprio** (`cms.<host>`), o que isola cookie/sessão do portal (ADR-005/037).
 * O host é derivado do `BASE_URL` (o app roteia por Host; `*.localhost` resolve para loopback).
 */
const cmsBaseURL = process.env.CMS_BASE_URL ?? new URL(baseURL).origin.replace('://', '://cms.');

export default defineConfig({
  testDir: './tests',
  outputDir: './test-results',

  fullyParallel: false,
  // Arquivos em paralelo (determinístico); testes dentro do arquivo continuam seriais.
  workers: Number(process.env.E2E_WORKERS ?? 4),
  retries: 0,
  forbidOnly: !!process.env.CI,

  timeout: 30_000,
  expect: { timeout: 7_000 },

  reporter: [['list'], ['html', { open: 'never', outputFolder: './report' }]],

  use: {
    baseURL,
    locale: 'pt-BR',
    timezoneId: 'America/Sao_Paulo',
    colorScheme: 'light',
    actionTimeout: 10_000,
    navigationTimeout: 15_000,
    trace: 'retain-on-failure',
    // Local Network Access (ex-PNA) bloqueia `loopback -> loopback` quando as origens diferem,
    // antes do CORS. O teste 12 prova CORS a partir de um consumidor cross-origin; a checagem de
    // LNA é outra política (e não existe em produção, onde o consumidor é público).
    launchOptions: { args: ['--disable-features=LocalNetworkAccessChecks'] },
    screenshot: 'only-on-failure',
    video: 'off',
    testIdAttribute: 'data-testid',
  },

  projects: [
    {
      // Lote **global** (tema/shell/menu, ativação/manutenção do suporte, home publicada e o
      // perfil de layout): roda sozinho antes dos demais (dependencies abaixo), com **um** worker.
      // 18, 23, 26, 30, 31 e 32 mutam estado compartilhado por todo o portal/painel; `workers: 1`
      // garante que os arquivos não rodem em paralelo.
      name: 'cms-serial',
      testMatch:
        /(?:18-estrutura-site|23-suporte-painel|26-cms-publicacao-home|30-cms-widgets-slots|31-cms-home-composicao|32-cms-banner-vigencia)\.spec\.ts/,
      workers: 1,
      use: {
        ...devices['Desktop Chrome'],
        baseURL: cmsBaseURL,
        viewport: { width: 1366, height: 768 },
      },
    },
    {
      name: 'portal-desktop',
      dependencies: ['cms-serial'],
      testIgnore: [
        /no-js\.spec\.ts/,
        /cms-.*\.spec\.ts/,
        /23-suporte-painel\.spec\.ts/,
        /18-estrutura-site\.spec\.ts/,
        /24-estatisticas\.spec\.ts/,
      ],
      use: { ...devices['Desktop Chrome'], viewport: { width: 1366, height: 768 } },
    },
    {
      name: 'portal-mobile',
      dependencies: ['cms-serial'],
      testIgnore: [
        /no-js\.spec\.ts/,
        /cms-.*\.spec\.ts/,
        /23-suporte-painel\.spec\.ts/,
        /18-estrutura-site\.spec\.ts/,
        /24-estatisticas\.spec\.ts/,
      ],
      use: { ...devices['Pixel 7'] },
    },
    {
      name: 'portal-no-js',
      dependencies: ['cms-serial'],
      testMatch: /no-js\.spec\.ts/,
      use: {
        ...devices['Desktop Chrome'],
        viewport: { width: 1366, height: 768 },
        javaScriptEnabled: false,
      },
    },
    {
      // Painel: domínio próprio + axe (o CMS não é indexável nem multi-idioma por URL).
      name: 'cms-desktop',
      dependencies: ['cms-serial'],
      testMatch:
        /(?:07-cms-shell|08-cms-noticias|10-cms-layout|15-cms-galeria-lote|17-cms-configuracoes|19-cms-usuarios|20-cms-papeis|21-cms-perfil|24-estatisticas|25-cms-editor-home|27-cms-paginas|28-cms-paginas-portal|29-cms-destaques|33-cms-dados-abertos-fonte|34-cms-listas-formularios)\.spec\.ts/,
      use: {
        ...devices['Desktop Chrome'],
        baseURL: cmsBaseURL,
        viewport: { width: 1366, height: 768 },
      },
    },
    {
      // Painel em ponteiro grosso: off-canvas, alvos de toque e axe medidos no viewport real.
      // `22-cms-acesso-mobile` cobre as telas da P2 no mobile e o bloco sem JS da matriz.
      // Depende também do `cms-desktop`: o editor da home (`25`) muta o **mesmo rascunho** e dois
      // projetos concorrentes disputariam `lock_version` (409 determinístico, ADR-001).
      name: 'cms-mobile',
      dependencies: ['cms-serial', 'cms-desktop'],
      testMatch: /(?:16-cms-mobile|22-cms-acesso-mobile|25-cms-editor-home|27-cms-paginas|28-cms-paginas-portal|29-cms-destaques|34-cms-listas-formularios)\.spec\.ts/,
      use: {
        ...devices['Pixel 7'],
        baseURL: cmsBaseURL,
      },
    },
  ],
});
