import { expect, test } from '@playwright/test';
import { expectNoA11yViolations } from './support/axe';
import { signIn } from './support/cms';

/**
 * História 20 — Perfis e matriz de permissões (P2.S4/ADR-033).
 *
 * Jornada: o administrador abre a lista de perfis, cria um perfil marcando uma ação declarada
 * **pelo teclado**, confere a matriz (ação não declarada desabilitada), encontra a linha e exclui
 * o perfil criado — sem depender de JS para a matriz e sem deixar dado de teste.
 */
test.describe('CMS — Perfis', () => {
  const stamp = Date.now();
  const name = `Perfil E2E ${stamp}`;

  test('cria perfil pela matriz, confere a lista e exclui', async ({ page }) => {
    await signIn(page);

    await page.goto('/papeis');
    await expect(page.getByRole('heading', { name: 'Perfis', level: 1 })).toBeVisible();
    await expect(page.getByRole('table', { name: 'Perfis de acesso' })).toBeVisible();
    await expectNoA11yViolations(page);

    await page.getByRole('link', { name: 'Novo perfil' }).click();
    await expect(page).toHaveURL(/\/papeis\/criar$/);
    await expect(page.getByRole('table', { name: 'Matriz de permissões por módulo' })).toBeVisible();
    await expect(page.getByText(/módulos com edição/)).toBeVisible();
    await expectNoA11yViolations(page);

    await page.locator('#field-nome').fill(name);

    // Operação por teclado: foco no checkbox nativo e ativação por Espaço (sem clique).
    const noticiasView = page.locator('#perm-Noticias-ver');
    await noticiasView.focus();
    await page.keyboard.press('Space');
    await expect(noticiasView).toBeChecked();

    // Ação não declarada pelo módulo existe, mas está desabilitada (não omitida).
    const undeclared = page.locator('input[value="blueprint.editar"]');
    await expect(undeclared).toBeDisabled();

    await page.getByRole('button', { name: 'Salvar' }).click();

    await expect(page).toHaveURL(/\/papeis$/);
    await expect(page.getByText('Perfil criado.')).toBeVisible();

    // Banco de dev persistente: a lista só ordena por nome e acumula perfis de execuções
    // anteriores. O filtro `q` localiza a própria linha em qualquer página.
    await page.goto(`/papeis?q=${encodeURIComponent(name)}`);

    const row = page.locator('tbody tr', { hasText: name });
    await expect(row).toHaveCount(1);
    await expectNoA11yViolations(page);

    const trigger = row.getByRole('button', { name: 'Excluir' });
    const popoverId = await trigger.getAttribute('popovertarget');
    expect(popoverId).toBeTruthy();

    await trigger.click();

    const dialog = page.locator(`#${popoverId}`);
    await expect(dialog).toBeVisible();
    await dialog.getByRole('button', { name: 'Excluir' }).click();

    await expect(page).toHaveURL(/\/papeis$/);
    await expect(page.getByText('Perfil excluído.')).toBeVisible();
    await expect(row).toHaveCount(0);
    await expectNoA11yViolations(page);
  });
});
