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

/**
 * História 19 — Usuários do painel (P2.S3/ADR-033).
 *
 * Jornada: o administrador cria um operador com o perfil Administrador, o operador entra, o
 * administrador desativa a conta e o login seguinte falha com a mensagem genérica. Cada execução
 * cria a própria identidade (e-mail único) — nenhum spec depende deste dado.
 */
test.describe('CMS — Usuários', () => {
  const stamp = Date.now();
  const email = `e2e-acesso-${stamp}@concordia.test`;
  const name = `Operador E2E ${stamp}`;
  const password = 'E2eAcesso#2026';

  test('cria usuário, entra, desativa e o login falha', async ({ page }) => {
    await signIn(page);

    await page.goto('/usuarios');
    await expect(page.getByRole('heading', { name: 'Usuários', level: 1 })).toBeVisible();
    await expect(page.getByRole('table', { name: 'Usuários do painel' })).toBeVisible();
    await expectNoA11yViolations(page);

    await page.getByRole('link', { name: 'Novo usuário' }).click();
    await expect(page).toHaveURL(/\/usuarios\/criar$/);
    await expectNoA11yViolations(page);

    await page.getByLabel('Nome').fill(name);
    await page.getByLabel('E-mail').fill(email);
    await page.getByLabel('Perfil').selectOption({ label: 'Administrador' });
    await page.locator('#field-password').fill(password);
    await page.locator('#field-password_confirmation').fill(password);
    await page.getByRole('button', { name: 'Salvar' }).click();

    await expect(page).toHaveURL(/\/usuarios$/);
    await expect(page.getByText('Usuário criado.')).toBeVisible();

    // A lista cresce a cada execução (exclusão física é proibida): localiza a própria linha pelo
    // filtro `q`, nunca pela página 1 — senão o spec quebra ao acumular >15 contas no banco dev.
    const filtered = `/usuarios?q=${encodeURIComponent(email)}`;
    await page.goto(filtered);
    await expect(page.locator('tbody tr', { hasText: name })).toHaveCount(1);
    await expectNoA11yViolations(page);

    // Operador criado entra no painel.
    await signOut(page);
    await expect(page).toHaveURL(/\/login$/);
    await page.getByLabel('E-mail').fill(email);
    await page.getByLabel('Senha').fill(password);
    await Promise.all([
      page.waitForURL(/\/$/, { timeout: 30_000 }),
      page.getByRole('button', { name: 'Entrar' }).click(),
    ]);
    await expect(page.getByRole('heading', { name: 'Painel', level: 1 })).toBeVisible();

    // Volta ao administrador e desativa a conta pela confirmação nativa.
    await signOut(page);
    await expect(page).toHaveURL(/\/login$/);
    await signIn(page);
    await page.goto(filtered);

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

    const trigger = row.getByRole('button', { name: 'Desativar' });
    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: 'Desativar' }).click();

    await expect(page).toHaveURL(/\/usuarios$/);
    await expect(page.getByText('Usuário desativado.')).toBeVisible();
    await expectNoA11yViolations(page);

    // A conta desativada não autentica mais (mensagem genérica, sem revelar estado).
    await signOut(page);
    await expect(page).toHaveURL(/\/login$/);
    await page.getByLabel('E-mail').fill(email);
    await page.getByLabel('Senha').fill(password);
    await page.getByRole('button', { name: 'Entrar' }).click();

    await expect(page.getByText('Credenciais inválidas.')).toBeVisible();
    await expect(page).toHaveURL(/\/login$/);
    await expectNoA11yViolations(page);
  });
});
