// =============================================================================
// T#10 — Golden path: paciente abre link → preenche → submit → sucesso
// =============================================================================
// Strategy: intercepta as chamadas pra Supabase Functions/REST e responde
// com mocks. Sem precisar de banco real ou edge functions rodando.
//
// Cobre as camadas de defesa em camadas (A#20 rev2):
//   - honeypot (campo invisível, garantimos que não preenchemos)
//   - submit normal funciona
//   - 403 captcha-required → componente MathCaptchaChallenge aparece
//   - 429 rate-limited → toast amigável
//   - token UUID inválido bloqueia a página
// =============================================================================
import { test, expect } from '@playwright/test';

const VALID_TOKEN = '550e8400-e29b-41d4-a716-446655440000'; // UUID v4 válido (TOKEN_RX bate)
const PUBLIC_URL = `/cadastro/paciente?t=${VALID_TOKEN}`;

const FUNCTIONS_RX = /\/functions\/v1\/submit-patient-intake/;

// Helper: preenche os 3 campos obrigatórios + consent
async function fillRequired(page, { nome, email, telefone }) {
    await page.locator('#f_nome').fill(nome);
    await page.locator('#f_email_principal').fill(email);
    await page.locator('#f_telefone').fill(telefone);
    // PrimeVue Checkbox é um div com role=checkbox; .check() não funciona, precisa click
    await page.locator('label[for="ext_consent"]').click();
}

test.describe('Cadastro paciente externo — golden path', () => {
    test('paciente preenche e submete com sucesso (sem captcha)', async ({ page }) => {
        await page.route(FUNCTIONS_RX, async (route) => {
            const body = route.request().postDataJSON();

            // honeypot NÃO foi preenchido (humano)
            expect(body?.website).toBeFalsy();
            expect(body?.token).toBe(VALID_TOKEN);
            expect(body?.payload?.nome_completo).toBe('Maria da Silva');
            expect(body?.payload?.consent).toBe(true);

            await route.fulfill({
                status: 200,
                contentType: 'application/json',
                body: JSON.stringify({ ok: true, intake_id: 'fake-intake-uuid' })
            });
        });

        await page.goto(PUBLIC_URL);
        await expect(page.getByText('Pré-cadastro do paciente')).toBeVisible();

        await fillRequired(page, {
            nome: 'Maria da Silva',
            email: 'maria@test.com',
            telefone: '11987654321'
        });

        await page.getByRole('button', { name: 'Enviar cadastro', exact: true }).click();
        await expect(page.getByText(/Enviado com sucesso/i).first()).toBeVisible({ timeout: 10_000 });
    });

    test('rate limit (429) mostra mensagem amigável de tentativas', async ({ page }) => {
        await page.route(FUNCTIONS_RX, async (route) => {
            await route.fulfill({
                status: 429,
                contentType: 'application/json',
                body: JSON.stringify({ error: 'rate-limited', retry_after_seconds: 600 })
            });
        });

        await page.goto(PUBLIC_URL);
        await expect(page.getByText('Pré-cadastro do paciente')).toBeVisible();

        await fillRequired(page, {
            nome: 'João Bot',
            email: 'joao@test.com',
            telefone: '11999999999'
        });

        await page.getByRole('button', { name: 'Enviar cadastro', exact: true }).click();
        await expect(page.getByText(/Muitas tentativas/i)).toBeVisible({ timeout: 6_000 });
    });

    test('captcha-required mostra MathCaptchaChallenge e bloqueia botão até resposta', async ({ page }) => {
        let firstSubmitCall = true;

        await page.route(FUNCTIONS_RX, async (route) => {
            const url = route.request().url();
            if (url.includes('/captcha-challenge')) {
                await route.fulfill({
                    status: 200,
                    contentType: 'application/json',
                    body: JSON.stringify({ challenge: { id: 'fake-challenge-id', question: 'Quanto é 2 + 3?' } })
                });
                return;
            }
            if (firstSubmitCall) {
                firstSubmitCall = false;
                await route.fulfill({
                    status: 403,
                    contentType: 'application/json',
                    body: JSON.stringify({ error: 'captcha-required' })
                });
                return;
            }
            // segunda call: ok
            await route.fulfill({
                status: 200,
                contentType: 'application/json',
                body: JSON.stringify({ ok: true, intake_id: 'after-captcha' })
            });
        });

        await page.goto(PUBLIC_URL);
        await expect(page.getByText('Pré-cadastro do paciente')).toBeVisible();

        await fillRequired(page, {
            nome: 'Ana Pereira',
            email: 'ana@test.com',
            telefone: '11955554444'
        });

        await page.getByRole('button', { name: 'Enviar cadastro', exact: true }).click();

        // MathCaptchaChallenge aparece
        await expect(page.getByText('Quanto é 2 + 3?')).toBeVisible({ timeout: 8_000 });

        // Botão "Enviar cadastro" do footer fica disabled enquanto sem resposta
        await expect(page.getByRole('button', { name: 'Enviar cadastro', exact: true })).toBeDisabled();
    });

    test('honeypot field existe no DOM mas está fora da viewport', async ({ page }) => {
        await page.goto(PUBLIC_URL);
        await expect(page.getByText('Pré-cadastro do paciente')).toBeVisible();

        const honeypot = page.locator('input#ext_website');
        await expect(honeypot).toHaveCount(1);
        await expect(honeypot).not.toBeInViewport();
    });

    test('token inválido bloqueia toda a página de cadastro', async ({ page }) => {
        await page.goto('/cadastro/paciente?t=token-invalido');

        // Mensagem de erro aparece
        await expect(page.getByText(/Link inválido ou ausente/i)).toBeVisible();

        // Form não renderiza (botão Enviar não existe)
        await expect(page.getByRole('button', { name: 'Enviar cadastro', exact: true })).toHaveCount(0);
    });
});
