<!--
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/views/pages/public/CadastroPacienteExterno.vue
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
-->
<script setup>
import { computed, reactive, ref, onMounted, onBeforeUnmount, nextTick, watch } from 'vue';
import { useRoute } from 'vue-router';

import InputMask from 'primevue/inputmask';
import Textarea from 'primevue/textarea';
import Checkbox from 'primevue/checkbox';
import Message from 'primevue/message';
import Popover from 'primevue/popover';
import Dialog from 'primevue/dialog';
import Accordion from 'primevue/accordion';
import AccordionPanel from 'primevue/accordionpanel';
import AccordionHeader from 'primevue/accordionheader';
import AccordionContent from 'primevue/accordioncontent';
import Select from 'primevue/select';

import { useToast } from 'primevue/usetoast';
import { supabase } from '@/lib/supabase/client';
import { digitsOnly, isValidEmail, toISODate, generateCPF, fmtCPF } from '@/utils/validators';
import MathCaptchaChallenge from '@/components/security/MathCaptchaChallenge.vue';

const route = useRoute();
const toast = useToast();

const isDev = import.meta.env.DEV;

// A#20 rev2 — defesa em camadas self-hosted
// Honeypot: campo invisível que humano nunca preenche
const honeypot = ref('');
// Math captcha: ativado sob demanda quando edge function devolve 403 captcha-required
const captchaRequired = ref(false);
const captchaId = ref('');
const captchaAnswer = ref(null);

const salvando = ref(false);
const sucesso = ref(false);

// A#25: dialog de política de privacidade (LGPD)
const policyOpen = ref(false);

const token = computed(() => String(route.query.t || '').trim());
// A#21: validação mais estrita — aceita UUID (com ou sem hífen, 32 hex chars).
// Ainda é cosmético (servidor valida de verdade), mas reduz falsos "verificado".
const TOKEN_RX = /^[0-9a-f]{32}$|^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
const tokenOk = computed(() => TOKEN_RX.test(token.value));

// ------------------------------------------------------
// A#31 — Hero header: lookup público do terapeuta/clínica
// ------------------------------------------------------
const inviteInfo = ref(null);
const loadingInfo = ref(false);
const heroAvatarFailed = ref(false);
const heroLogoFailed = ref(false);

const WORK_DESCRIPTION_LABEL = {
    psicologo_clinico: 'Psicólogo(a) Clínico(a)',
    psicanalista: 'Psicanalista',
    psiquiatra: 'Psiquiatra',
    psicoterapeuta: 'Psicoterapeuta',
    neuropsicologo: 'Neuropsicólogo(a)',
    psicologo_organizacional: 'Psicólogo(a) Organizacional',
    psicologo_escolar: 'Psicólogo(a) Escolar',
    psicologo_hospitalar: 'Psicólogo(a) Hospitalar',
    coach_mentor: 'Coach / Mentor(a)',
    terapeuta_holistico: 'Terapeuta Holístico(a)',
    outro: 'Profissional da saúde mental'
};

const heroTherapist = computed(() => inviteInfo.value?.therapist || null);
const heroClinic = computed(() => inviteInfo.value?.clinic || null);

const heroDisplayName = computed(() => heroTherapist.value?.display_name || 'Profissional');
const heroFirstName = computed(() => String(heroDisplayName.value || '').trim().split(/\s+/)[0] || '');
const heroAvatar = computed(() => (!heroAvatarFailed.value ? heroTherapist.value?.avatar_url || '' : ''));
const heroClinicLogo = computed(() => (!heroLogoFailed.value ? heroClinic.value?.logo_url || '' : ''));
const heroWorkLabel = computed(() => {
    const key = heroTherapist.value?.work_description;
    if (!key) return '';
    return WORK_DESCRIPTION_LABEL[key] || 'Profissional da saúde mental';
});
const heroInitials = computed(() => {
    const parts = String(heroDisplayName.value || '').trim().split(/\s+/).filter(Boolean);
    if (!parts.length) return '·';
    if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
    return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
});
const hasBothLogos = computed(() => !!(heroAvatar.value && heroClinicLogo.value));

function _normalizeUrl(u) {
    const s = String(u || '').trim();
    if (!s) return '';
    if (/^https?:\/\//i.test(s)) return s;
    return `https://${s}`;
}
function _instagramUrl(handle) {
    const s = String(handle || '').trim().replace(/^@/, '');
    if (!s) return '';
    if (/^https?:\/\//i.test(s)) return s;
    return `https://instagram.com/${s}`;
}
function _firstSocialFromClinic(socials) {
    if (!Array.isArray(socials)) return null;
    for (const item of socials) {
        if (!item) continue;
        if (typeof item === 'string' && item.trim()) return { label: 'Rede social', href: _normalizeUrl(item), icon: 'pi pi-globe', external: true };
        if (typeof item === 'object') {
            const url = item.url || item.link || item.handle;
            const kind = String(item.platform || item.type || item.network || '').toLowerCase();
            if (!url) continue;
            const href = kind.includes('instagram') ? _instagramUrl(url) : _normalizeUrl(url);
            const icon = kind.includes('instagram') ? 'pi pi-instagram'
                       : kind.includes('facebook')  ? 'pi pi-facebook'
                       : kind.includes('youtube')   ? 'pi pi-youtube'
                       : kind.includes('linkedin')  ? 'pi pi-linkedin'
                       : 'pi pi-globe';
            return { label: item.platform || 'Rede social', href, icon, external: true };
        }
    }
    return null;
}

const heroContactChips = computed(() => {
    const chips = [];
    const t = heroTherapist.value || {};
    const c = heroClinic.value || {};

    // Endereço (clínica)
    const parts = [c.street, c.number].filter(Boolean).join(', ');
    const cityUf = [c.city, c.state].filter(Boolean).join(' · ');
    const addr = [parts, c.neighborhood, cityUf].filter(Boolean).join(' — ');
    if (addr) chips.push({ label: addr, href: `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(addr)}`, icon: 'pi pi-map-marker', external: true });

    // Telefone (prioriza clínica, cai pro pessoal)
    const phone = c.phone || t.phone;
    if (phone) {
        const digits = String(phone).replace(/\D/g, '');
        chips.push({ label: phone, href: digits ? `tel:+${digits.startsWith('55') ? digits : '55' + digits}` : `tel:${phone}`, icon: 'pi pi-phone', external: false });
    }

    // E-mail (clínica)
    if (c.email) chips.push({ label: c.email, href: `mailto:${c.email}`, icon: 'pi pi-envelope', external: false });

    // Site (prioriza clínica)
    const site = c.site || t.site_url;
    if (site) chips.push({ label: 'Site', href: _normalizeUrl(site), icon: 'pi pi-globe', external: true });

    // Instagram do terapeuta
    if (t.instagram) chips.push({ label: `@${String(t.instagram).replace(/^@/, '').replace(/^https?:\/\/(www\.)?instagram\.com\//i, '').replace(/\/$/, '')}`, href: _instagramUrl(t.instagram), icon: 'pi pi-instagram', external: true });

    // Rede social da clínica (primeira disponível, se ainda não houver instagram do terapeuta)
    if (!t.instagram) {
        const social = _firstSocialFromClinic(c.social);
        if (social) chips.push(social);
    }

    return chips;
});

async function fetchInviteInfo() {
    if (!tokenOk.value) return;
    loadingInfo.value = true;
    try {
        const { data, error } = await supabase.functions.invoke('get-intake-invite-info', {
            body: { token: token.value }
        });
        if (error) return;
        if (data?.ok && data.info) {
            inviteInfo.value = data.info;
        }
    } catch {
        // silencioso — sem hero é ok, form continua funcional
    } finally {
        loadingInfo.value = false;
    }
}

// ------------------------------------------------------
// Helpers (✅ ficam ANTES do enviar())
// ------------------------------------------------------
function cleanStr(v) {
    const s = String(v ?? '').trim();
    return s ? s : null;
}

// ------------------------------------------------------
// Mock fill (Preencher tudo)
// ------------------------------------------------------
function randInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}
function pick(arr) {
    return arr[randInt(0, arr.length - 1)];
}
function maybe(p = 0.5) {
    return Math.random() < p;
}
function pad2(n) {
    return String(n).padStart(2, '0');
}

function randomDateDDMMYYYY(minAge = 18, maxAge = 65) {
    const now = new Date();
    const age = randInt(minAge, maxAge);
    const year = now.getFullYear() - age;
    const month = randInt(1, 12);
    const day = randInt(1, 28);
    return `${pad2(day)}-${pad2(month)}-${year}`;
}

function randomPhoneBR() {
    const ddd = randInt(11, 99);
    const p1 = randInt(90000, 99999);
    const p2 = randInt(1000, 9999);
    return `(${ddd}) ${p1}-${p2}`;
}

function generateCPFFormatted() {
    return fmtCPF(generateCPF());
}

function generateRG() {
    const base = Array.from({ length: 8 }, () => randInt(0, 9));
    let sum = 0;
    for (let i = 0; i < 8; i++) sum += base[i] * (9 - i);
    const mod = sum % 11;
    let dv = 11 - mod;
    if (dv === 10) dv = 'X';
    else if (dv === 11) dv = 0;
    const rg = [...base, dv].join('');
    return rg.replace(/^(\d{2})(\d{3})(\d{3})([\dX])$/, '$1.$2.$3-$4');
}

function randomEmailFromName(name) {
    const slug = String(name || 'paciente')
        .normalize('NFD')
        .replace(/[\u0300-\u036f]/g, '')
        .toLowerCase()
        .replace(/[^a-z0-9]+/g, '.')
        .replace(/(^\.)|(\.$)/g, '');
    return `${slug}.${randInt(10, 999)}@email.com`;
}

function preencherMock() {
    const first = ['Ana', 'Bruno', 'Carla', 'Daniel', 'Eduarda', 'Felipe', 'Giovana', 'Henrique', 'Isabela', 'João', 'Larissa', 'Marcos', 'Nathalia', 'Otávio', 'Paula', 'Rafael', 'Sabrina', 'Thiago', 'Vanessa', 'Yasmin'];
    const last = ['Silva', 'Santos', 'Oliveira', 'Souza', 'Pereira', 'Lima', 'Ferreira', 'Almeida', 'Costa', 'Gomes', 'Ribeiro', 'Carvalho', 'Martins', 'Araújo', 'Barbosa'];
    const cities = ['São Carlos', 'Ribeirão Preto', 'Campinas', 'São Paulo', 'Araraquara', 'Bauru', 'Sorocaba', 'Santos'];
    const neighborhoods = ['Centro', 'Jardim Paulista', 'Vila Prado', 'Santa Felícia', 'Cidade Jardim'];
    const streets = ['Rua das Flores', 'Av. Brasil', 'Rua XV de Novembro', 'Av. São Carlos', 'Rua das Acácias'];

    const nome = `${pick(first)} ${pick(last)} ${pick(last)}`;
    const cidade = pick(cities);

    form.nome_completo = nome;
    form.data_nascimento = randomDateDDMMYYYY(18, 70);
    form.naturalidade = cidade;
    form.genero = pick(GENDER_OPTIONS).value;
    form.estado_civil = pick(MARITAL_OPTIONS).value;

    form.email_principal = randomEmailFromName(nome);
    form.email_alternativo = maybe(0.35) ? `alt.${randInt(10, 999)}@gmail.com` : `alt.${randInt(10, 999)}@hotmail.com`;

    form.telefone = randomPhoneBR();
    form.telefone_alternativo = maybe(0.35) ? randomPhoneBR() : '';

    form.cpf = generateCPFFormatted();
    form.rg = generateRG();

    form.observacoes = maybe(0.5) ? 'Cadastro realizado via link externo.' : 'Tenho disponibilidade no período da noite.';

    form.onde_nos_conheceu = pick(['Instagram', 'Google', 'Indicação', 'Site', 'Threads', 'Outro']);
    form.encaminhado_por = maybe(0.45) ? `${pick(first)} ${pick(last)}` : '';

    form.pais = 'Brasil';
    form.cep = '13561-260';
    form.cidade = cidade;
    form.estado = 'SP';
    form.endereco = pick(streets);
    form.numero = String(randInt(10, 9999));
    form.bairro = pick(neighborhoods);
    form.complemento = maybe(0.3) ? `Apto ${randInt(10, 999)}` : '';

    form.escolaridade = pick(['Ensino Fundamental', 'Ensino Médio', 'Superior incompleto', 'Superior completo', 'Pós-graduação']);
    form.profissao = pick(['Estudante', 'Professora', 'Desenvolvedor', 'Vendedor', 'Enfermeira', 'Autônomo', 'Servidor público']);

    const temParente = maybe(0.6);
    form.nome_parente = temParente ? `${pick(first)} ${pick(last)}` : '';
    form.grau_parentesco = temParente ? pick(['Mãe', 'Pai', 'Irmã', 'Irmão', 'Cônjuge', 'Tia', 'Avó', 'Amigo(a)']) : '';
    form.telefone_parente = temParente ? randomPhoneBR() : '';

    const temResponsavel = maybe(0.35);
    form.nome_responsavel = temResponsavel ? `${pick(first)} ${pick(last)} ${pick(last)}` : '';
    form.telefone_responsavel = temResponsavel ? randomPhoneBR() : '';
    form.cpf_responsavel = temResponsavel ? generateCPFFormatted() : '';
    form.observacao_responsavel = temResponsavel ? 'Responsável ciente e de acordo com o cadastro.' : '';
    form.cobranca_no_responsavel = temResponsavel ? maybe(0.5) : false;

    consent.value = true;
    toast.add({ severity: 'info', summary: 'Exemplo', detail: 'Campos preenchidos com dados simulados.', life: 1800 });
}

// Upload de foto removido da página pública (A#15):
// O bucket não aceita mais upload anônimo. O terapeuta pode pedir a foto
// depois, por outro canal, se for necessário.

// ------------------------------------------------------
// CEP (ViaCEP)
// ------------------------------------------------------
const cepLoading = ref(false);
const addressLocked = computed(() => salvando.value || cepLoading.value);

async function fetchCep(cepRaw) {
    const cep = String(cepRaw || '').replace(/\D/g, '');
    if (cep.length !== 8) return null;

    const res = await fetch(`https://viacep.com.br/ws/${cep}/json/`, {
        method: 'GET',
        headers: { Accept: 'application/json' }
    });
    if (!res.ok) return null;

    const data = await res.json();
    if (!data || data.erro) return null;
    return data;
}

async function onCepBlur() {
    if (cepLoading.value) return;

    const cepDigits = String(form.cep || '').replace(/\D/g, '');
    if (cepDigits.length !== 8) return;

    cepLoading.value = true;
    try {
        const d = await fetchCep(form.cep);
        if (!d) {
            toast.add({ severity: 'warn', summary: 'CEP', detail: 'CEP não encontrado.', life: 2500 });
            return;
        }

        form.cidade = d.localidade || form.cidade;
        form.estado = d.uf || form.estado;
        form.bairro = d.bairro || form.bairro;
        form.endereco = d.logradouro || form.endereco;
        if (!form.complemento) form.complemento = d.complemento || '';

        toast.add({ severity: 'success', summary: 'CEP', detail: 'Endereço preenchido automaticamente.', life: 1800 });
    } catch {
        toast.add({ severity: 'error', summary: 'CEP', detail: 'Falha ao consultar o ViaCEP.', life: 2500 });
    } finally {
        cepLoading.value = false;
    }
}

// ------------------------------------------------------
// Accordion + menu
// ------------------------------------------------------
const activeValue = ref('0');
const panelHeaderRefs = ref([]);

function setPanelHeaderRef(el, idx) {
    if (!el) return;
    panelHeaderRefs.value[idx] = el;
}

async function openPanel(i) {
    activeValue.value = String(i);
    await nextTick();
    const headerRef = panelHeaderRefs.value?.[i];
    const el = headerRef?.$el ?? headerRef;
    if (el && typeof el.scrollIntoView === 'function') {
        el.scrollIntoView({ behavior: 'smooth', block: 'start' });
    }
}

const navItems = [
    { value: '0', label: 'Informações pessoais', icon: 'pi pi-user' },
    { value: '1', label: 'Endereço', icon: 'pi pi-map-marker' },
    { value: '2', label: 'Dados adicionais', icon: 'pi pi-tags' },
    { value: '3', label: 'Responsável', icon: 'pi pi-users' }
];

const navPopover = ref(null);
function toggleNav(event) {
    navPopover.value?.toggle(event);
}
function selectNav(item) {
    openPanel(Number(item.value));
    navPopover.value?.hide();
}
const selectedNav = computed(() => navItems.find((i) => i.value === activeValue.value) || null);

const isCompact = ref(false);
let mql = null;
let mqlHandler = null;
function syncCompact() {
    isCompact.value = !!mql?.matches;
}

onMounted(() => {
    mql = window.matchMedia('(max-width: 1199px)');
    syncCompact();
    mqlHandler = () => syncCompact();
    if (mql.addEventListener) mql.addEventListener('change', mqlHandler);
    else mql.addListener(mqlHandler);

    fetchInviteInfo();
});

onBeforeUnmount(() => {
    if (mql && mqlHandler) {
        if (mql.removeEventListener) mql.removeEventListener('change', mqlHandler);
        else mql.removeListener(mqlHandler);
    }
});

// ------------------------------------------------------
// Options
// ------------------------------------------------------
const GENDER_OPTIONS = [
    { label: 'Masculino', value: 'male' },
    { label: 'Feminino', value: 'female' },
    { label: 'Não-binário', value: 'non_binary' },
    { label: 'Outro', value: 'other' },
    { label: 'Prefiro não informar', value: 'na' }
];

const MARITAL_OPTIONS = [
    { label: 'Solteiro(a)', value: 'single' },
    { label: 'Casado(a)', value: 'married' },
    { label: 'Divorciado(a)', value: 'divorced' },
    { label: 'Viúvo(a)', value: 'widowed' },
    { label: 'Prefiro não informar', value: 'na' }
];

// ------------------------------------------------------
// Form
// ------------------------------------------------------
function resetForm() {
    return {
        nome_completo: '',
        email_principal: '',
        telefone: '',
        cep: '',
        pais: 'Brasil',
        cidade: '',
        estado: 'SP',
        endereco: '',
        numero: '',
        bairro: '',
        complemento: '',
        data_nascimento: '', // DD-MM-YYYY
        naturalidade: '',
        genero: '',
        estado_civil: '',
        onde_nos_conheceu: '',
        encaminhado_por: '',
        observacoes: '',
        nacionalidade: '',

        email_alternativo: '',
        telefone_alternativo: '',
        cpf: '',
        rg: '',

        escolaridade: '',
        profissao: '',
        nome_parente: '',
        grau_parentesco: '',
        telefone_parente: '',

        nome_responsavel: '',
        telefone_responsavel: '',
        cpf_responsavel: '',
        observacao_responsavel: '',
        cobranca_no_responsavel: false
    };
}

const form = reactive(resetForm());
const consent = ref(false);

const errors = reactive({
    nome_completo: '',
    email_principal: '',
    email_alternativo: '',
    telefone: '',
    consentimento: ''
});

function validate() {
    errors.nome_completo = '';
    errors.email_principal = '';
    errors.email_alternativo = '';
    errors.telefone = '';
    errors.consentimento = '';

    const nome = String(form.nome_completo || '').trim();
    if (!nome) errors.nome_completo = 'Informe seu nome completo';
    if (!isValidEmail(form.email_principal)) errors.email_principal = 'Informe um e-mail válido';
    if (cleanStr(form.email_alternativo) && !isValidEmail(form.email_alternativo)) errors.email_alternativo = 'E-mail alternativo inválido';
    if (!digitsOnly(form.telefone)) errors.telefone = 'Informe um telefone para contato';
    if (!consent.value) errors.consentimento = 'É necessário marcar o consentimento.';

    return !errors.nome_completo && !errors.email_principal && !errors.email_alternativo && !errors.telefone && !errors.consentimento;
}

// ------------------------------------------------------
// Progress (conceitual e útil)
// ------------------------------------------------------
const progressPct = computed(() => {
    // contagem simples e honesta: dá sensação de avanço sem "gamificar demais"
    const checks = [!!cleanStr(form.nome_completo), !!digitsOnly(form.telefone), isValidEmail(form.email_principal), !!cleanStr(form.data_nascimento), !!cleanStr(form.cep), !!cleanStr(form.endereco), !!cleanStr(form.cidade), !!consent.value];
    const done = checks.filter(Boolean).length;
    return Math.round((done / checks.length) * 100);
});

// ------------------------------------------------------
// enviar (✅ corrigido: sem redeclarar helpers)
// ------------------------------------------------------
async function enviar() {
    if (!tokenOk.value) return;
    if (sucesso.value) return;

    const ok = validate();
    if (!ok) {
        toast.add({ severity: 'warn', summary: 'Atenção', detail: 'Revise os campos obrigatórios.', life: 2200 });
        openPanel(0);
        return;
    }

    const isoBirth = toISODate(form.data_nascimento);
    if (cleanStr(form.data_nascimento) && !isoBirth) {
        toast.add({ severity: 'warn', summary: 'Atenção', detail: 'Data de nascimento inválida (use DD-MM-AAAA).', life: 2500 });
        openPanel(0);
        return;
    }

    salvando.value = true;
    try {
        // A#17: notas_internas NÃO é enviado (campo interno do terapeuta, não
        // deve vir do paciente). A#15: avatar_url removido (upload não é mais
        // possível anonimamente). Todos os campos texto são recortados em
        // length máximo client-side (defesa em camadas — o RPC também valida).
        const truncate = (v, n) => {
            const s = cleanStr(v);
            return s ? String(s).slice(0, n) : null;
        };

        const payload = {
            // essenciais
            nome_completo: truncate(form.nome_completo, 200),
            email_principal: cleanStr(form.email_principal)?.toLowerCase().slice(0, 120) || null,
            telefone: digitsOnly(form.telefone),

            // alternativos
            email_alternativo: cleanStr(form.email_alternativo)?.toLowerCase().slice(0, 120) || null,
            telefone_alternativo: digitsOnly(form.telefone_alternativo) || null,

            // docs / endereço
            cpf: digitsOnly(form.cpf),
            rg: truncate(form.rg, 20),
            cep: digitsOnly(form.cep),

            pais: truncate(form.pais, 60) || 'Brasil',
            cidade: truncate(form.cidade, 120),
            estado: truncate(form.estado, 2) || 'SP',
            endereco: truncate(form.endereco, 200),
            numero: truncate(form.numero, 20),
            bairro: truncate(form.bairro, 120),
            complemento: truncate(form.complemento, 120),

            // pessoais
            data_nascimento: isoBirth || null,
            naturalidade: truncate(form.naturalidade, 120),
            genero: cleanStr(form.genero),
            estado_civil: cleanStr(form.estado_civil),

            // adicionais
            profissao: truncate(form.profissao, 120),
            escolaridade: truncate(form.escolaridade, 120),
            nacionalidade: truncate(form.nacionalidade, 80),

            // origem + observações
            onde_nos_conheceu: truncate(form.onde_nos_conheceu, 80),
            encaminhado_por: truncate(form.encaminhado_por, 120),
            observacoes: truncate(form.observacoes, 2000),

            // consent
            consent: !!consent.value
        };

        Object.keys(payload).forEach((k) => {
            if (payload[k] === undefined) delete payload[k];
        });

        // A#24: envia user_agent pra log de tentativas (sem PII).
        const clientInfo = (typeof navigator !== 'undefined' && navigator.userAgent)
            ? String(navigator.userAgent).slice(0, 500)
            : null;

        // A#20 rev2: se já está exigindo captcha mas usuário não respondeu, bloqueia local
        if (captchaRequired.value && (!captchaId.value || captchaAnswer.value == null)) {
            toast.add({ severity: 'warn', summary: 'Verificação', detail: 'Responda a pergunta de verificação antes de enviar.', life: 3000 });
            salvando.value = false;
            return;
        }

        const { data, error } = await supabase.functions.invoke('submit-patient-intake', {
            body: {
                token: token.value,
                payload,
                website: honeypot.value,                          // honeypot field
                captcha_id: captchaId.value || null,
                captcha_answer: captchaAnswer.value,
                client_info: clientInfo
            }
        });

        // Quando edge devolve 4xx/5xx, supabase-js coloca a Response em error.context.
        // O body com {error: 'captcha-required' | 'rate-limited' | ...} continua acessível.
        let errBody = null;
        if (error?.context?.json) {
            try { errBody = await error.context.json(); } catch { /* sem body */ }
        }
        const errMsg = String(errBody?.error || data?.error || error?.message || '');
        if (/captcha-required/i.test(errMsg)) {
            captchaRequired.value = true;
            captchaId.value = '';
            captchaAnswer.value = null;
            toast.add({ severity: 'warn', summary: 'Verificação extra', detail: 'Por segurança, responda a pergunta abaixo.', life: 3500 });
            salvando.value = false;
            return;
        }

        if (/captcha-wrong/i.test(errMsg)) {
            captchaId.value = '';
            captchaAnswer.value = null;
            toast.add({ severity: 'warn', summary: 'Verificação', detail: 'Resposta incorreta. Tente novamente.', life: 3500 });
            salvando.value = false;
            return;
        }

        if (/rate-limited/i.test(errMsg)) {
            const retryAfter = errBody?.retry_after_seconds || data?.retry_after_seconds;
            const after = retryAfter ? Math.ceil(retryAfter / 60) : null;
            toast.add({
                severity: 'warn',
                summary: 'Muitas tentativas',
                detail: after ? `Tente novamente em ${after} min.` : 'Tente novamente mais tarde.',
                life: 6000
            });
            salvando.value = false;
            return;
        }

        if (error) throw new Error(data?.message || error.message || 'Falha ao enviar');
        if (data?.error) throw new Error(data?.message || data.error);

        sucesso.value = true;
        toast.add({ severity: 'success', summary: 'Enviado', detail: 'Cadastro enviado com sucesso.', life: 2500 });
    } catch (err) {
        toast.add({
            severity: 'error',
            summary: 'Falha ao enviar',
            detail: err?.message || 'Não foi possível enviar. Verifique o link e tente novamente.',
            life: 4500
        });
    } finally {
        salvando.value = false;
    }
}

// auto-cep
watch(
    () => form.cep,
    (newVal, oldVal) => {
        const d = String(newVal || '').replace(/\D/g, '');
        const prev = String(oldVal || '').replace(/\D/g, '');
        if (d.length === 8 && d !== prev) onCepBlur();
    }
);
</script>

<template>
    <Toast />
    <div class="min-h-screen bg-gradient-to-b from-slate-950 via-slate-900 to-slate-950 text-slate-100">
        <!-- "Backdrop" conceitual -->
        <div class="pointer-events-none fixed inset-0 opacity-30">
            <div class="absolute -top-24 left-1/2 h-72 w-72 -translate-x-1/2 rounded-full bg-emerald-400 blur-3xl" />
            <div class="absolute top-40 left-16 h-56 w-56 rounded-full bg-indigo-400 blur-3xl" />
            <div class="absolute bottom-24 right-16 h-64 w-64 rounded-full bg-fuchsia-400 blur-3xl" />
        </div>

        <div class="relative mx-auto flex min-h-screen max-w-6xl flex-col gap-6 px-4 py-10">
            <!-- A#31 — Hero header (NEW): quem te convidou -->
            <section v-if="tokenOk && !sucesso" class="mx-auto w-full max-w-[1100px]">
                <!-- Skeleton durante o fetch -->
                <div v-if="loadingInfo && !inviteInfo" class="rounded-3xl border border-white/10 bg-white/5 p-6 shadow-xl backdrop-blur-xl md:p-8">
                    <div class="flex animate-pulse flex-col gap-4 md:flex-row md:items-center md:gap-6">
                        <div class="h-24 w-24 shrink-0 rounded-2xl bg-white/10 md:h-28 md:w-28" />
                        <div class="flex-1 space-y-3">
                            <div class="h-5 w-40 rounded bg-white/10" />
                            <div class="h-4 w-56 rounded bg-white/10" />
                            <div class="h-3 w-72 rounded bg-white/10" />
                        </div>
                    </div>
                </div>

                <!-- Card carregado -->
                <div
                    v-else-if="inviteInfo"
                    class="relative overflow-hidden rounded-3xl border border-white/10 bg-gradient-to-br from-emerald-500/10 via-white/5 to-indigo-500/10 p-6 shadow-2xl backdrop-blur-xl md:p-8"
                >
                    <!-- Ornamento sutil -->
                    <div class="pointer-events-none absolute -top-20 -right-20 h-52 w-52 rounded-full bg-emerald-400/20 blur-3xl" aria-hidden="true" />
                    <div class="pointer-events-none absolute -bottom-20 -left-16 h-48 w-48 rounded-full bg-indigo-400/15 blur-3xl" aria-hidden="true" />

                    <div class="relative flex flex-col gap-6 md:flex-row md:items-center">
                        <!-- Avatar / Logo -->
                        <div class="relative shrink-0 self-center md:self-auto">
                            <img
                                v-if="heroAvatar"
                                :src="heroAvatar"
                                :alt="heroDisplayName"
                                class="h-24 w-24 rounded-2xl border border-white/20 object-cover shadow-lg md:h-28 md:w-28"
                                @error="heroAvatarFailed = true"
                            />
                            <div
                                v-else
                                class="grid h-24 w-24 place-items-center rounded-2xl border border-white/20 bg-gradient-to-br from-emerald-400/30 to-indigo-400/30 text-2xl font-semibold text-slate-50 shadow-lg md:h-28 md:w-28 md:text-3xl"
                            >
                                {{ heroInitials }}
                            </div>
                            <!-- Logo da clínica como badge quando ambos existem -->
                            <div
                                v-if="hasBothLogos"
                                class="absolute -bottom-2 -right-2 h-11 w-11 overflow-hidden rounded-xl border-2 border-slate-900 bg-white shadow-lg"
                                :title="heroClinic?.name || ''"
                            >
                                <img :src="heroClinicLogo" alt="" class="h-full w-full object-contain p-1" @error="heroLogoFailed = true" />
                            </div>
                        </div>

                        <!-- Identidade -->
                        <div class="min-w-0 flex-1 text-center md:text-left">
                            <div v-if="heroClinic?.name" class="text-[11px] font-semibold uppercase tracking-[0.14em] text-emerald-200/90">
                                {{ heroClinic.name }}
                            </div>
                            <h1 class="mt-1 text-2xl font-semibold tracking-tight text-slate-50 md:text-3xl">
                                {{ heroDisplayName }}
                            </h1>
                            <div v-if="heroWorkLabel" class="mt-1 text-sm text-slate-300">
                                {{ heroWorkLabel }}
                            </div>
                            <p
                                v-if="heroTherapist?.bio"
                                class="mx-auto mt-3 max-w-2xl text-sm leading-relaxed text-slate-200/90 md:mx-0"
                                style="display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;"
                            >
                                {{ heroTherapist.bio }}
                            </p>

                            <!-- Contatos -->
                            <div v-if="heroContactChips.length" class="mt-4 flex flex-wrap items-center justify-center gap-2 md:justify-start">
                                <a
                                    v-for="chip in heroContactChips"
                                    :key="chip.icon + chip.label"
                                    :href="chip.href"
                                    :target="chip.external ? '_blank' : '_self'"
                                    :rel="chip.external ? 'noopener noreferrer' : undefined"
                                    class="inline-flex max-w-full items-center gap-2 rounded-full border border-white/15 bg-white/5 px-3 py-1.5 text-xs text-slate-100 transition hover:border-white/30 hover:bg-white/10"
                                >
                                    <i :class="chip.icon" />
                                    <span class="truncate">{{ chip.label }}</span>
                                </a>
                            </div>
                        </div>
                    </div>

                    <!-- Boas-vindas -->
                    <div class="relative mt-6 rounded-2xl border border-emerald-400/20 bg-emerald-400/5 px-4 py-3 text-sm text-slate-100/95">
                        <div class="flex items-start gap-3">
                            <i class="pi pi-heart-fill mt-0.5 text-emerald-300" />
                            <div>
                                <span v-if="heroFirstName">Olá! Aqui é {{ heroFirstName }}. </span>
                                <span v-else>Olá! </span>
                                Que bom ter você por aqui. Para organizarmos nosso primeiro contato, preencha o formulário abaixo com calma —
                                leva poucos minutos e os campos opcionais podem ficar em branco.
                            </div>
                        </div>
                    </div>
                </div>
            </section>

            <!-- Modal container -->
            <div class="mx-auto w-full max-w-[1100px]">
                <div class="rounded-3xl border border-white/10 bg-white/5 shadow-2xl backdrop-blur-xl">
                    <!-- Header -->
                    <div class="flex flex-col gap-4 border-b border-white/10 px-6 py-6 md:flex-row md:items-center md:justify-between">
                        <div class="min-w-0">
                            <div class="flex items-center gap-3">
                                <div class="grid h-11 w-11 place-items-center rounded-2xl bg-white/10">
                                    <i class="pi pi-user text-lg opacity-90" />
                                </div>
                                <div class="min-w-0">
                                    <div class="text-xl font-semibold tracking-tight">Pré-cadastro do paciente</div>
                                    <div class="mt-0.5 text-sm text-slate-300">Preencha no seu tempo. O que for opcional pode ficar em branco.</div>
                                </div>
                            </div>

                            <!-- status strip -->
                            <div class="mt-4 flex flex-wrap items-center gap-2">
                                <span class="inline-flex items-center gap-2 rounded-full border px-3 py-1 text-xs" :class="tokenOk ? 'border-emerald-400/30 bg-emerald-400/10 text-emerald-100' : 'border-rose-400/30 bg-rose-400/10 text-rose-100'">
                                    <i :class="tokenOk ? 'pi pi-check' : 'pi pi-times'" />
                                    {{ tokenOk ? 'Link verificado' : 'Link inválido' }}
                                </span>

                                <span class="inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/5 px-3 py-1 text-xs text-slate-200">
                                    <i class="pi pi-lock" />
                                    Privacidade: uso apenas para contato e organização do atendimento
                                </span>

                                <span v-if="tokenOk && !sucesso" class="inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/5 px-3 py-1 text-xs text-slate-200">
                                    <i class="pi pi-chart-line" />
                                    Progresso: <b class="font-semibold">{{ progressPct }}%</b>
                                </span>
                            </div>

                            <!-- progress bar -->
                            <div v-if="tokenOk && !sucesso" class="mt-3 h-2 w-full overflow-hidden rounded-full bg-white/10">
                                <div class="h-full rounded-full bg-emerald-400/70 transition-all" :style="{ width: progressPct + '%' }" />
                            </div>
                        </div>

                        <!-- actions -->
                        <div class="flex shrink-0 flex-wrap items-center gap-2">
                            <!-- A#26: Botão de preencher mock apenas em DEV -->
                            <Button v-if="isDev" label="Preencher exemplo" icon="pi pi-bolt" severity="secondary" outlined class="!border-white/20 !text-slate-100" :disabled="salvando || sucesso || !tokenOk" @click="preencherMock" />
                            <Button label="Enviar" icon="pi pi-send" class="!bg-emerald-400/90 !border-emerald-400/50 !text-slate-950" :loading="salvando" :disabled="salvando || sucesso || !tokenOk" @click="enviar" />
                        </div>
                    </div>

                    <!-- Body states -->
                    <div class="px-6 py-6">
                        <Message v-if="!tokenOk" severity="error" :closable="false" class="mb-4"> Link inválido ou ausente. Verifique se você recebeu a URL completa. </Message>

                        <Message v-else-if="sucesso" severity="success" :closable="false" class="mb-4"> Enviado com sucesso. Você pode fechar esta página. </Message>

                        <div v-else class="grid grid-cols-12 gap-4">
                            <!-- Left panel (inside modal) -->
                            <aside class="col-span-12 md:col-span-4">
                                <div class="rounded-2xl border border-white/10 bg-white/5 p-4">
                                    <!-- Section chips -->
                                    <div>
                                        <div class="text-xs font-semibold text-slate-200">Seções</div>
                                        <div class="mt-2 flex flex-wrap gap-2">
                                            <button
                                                v-for="item in navItems"
                                                :key="item.value"
                                                type="button"
                                                class="inline-flex items-center gap-2 rounded-full border px-3 py-1 text-xs transition"
                                                :class="activeValue === item.value ? 'border-emerald-400/30 bg-emerald-400/10 text-emerald-100' : 'border-white/10 bg-white/5 text-slate-200 hover:bg-white/10'"
                                                @click="openPanel(Number(item.value))"
                                            >
                                                <i :class="item.icon" />
                                                <span class="max-w-[160px] truncate">{{ item.label }}</span>
                                            </button>
                                        </div>
                                    </div>

                                    <!-- Privacy note -->
                                    <div class="mt-5 rounded-2xl border border-white/10 bg-white/5 p-4">
                                        <div class="flex items-center gap-2 text-sm font-semibold">
                                            <i class="pi pi-shield text-slate-200" />
                                            Privacidade
                                        </div>
                                        <div class="mt-2 text-xs text-slate-300">Seus dados serão usados apenas para contato e organização do atendimento. Se algo falhar, peça um novo link ao terapeuta.</div>
                                    </div>
                                </div>
                            </aside>

                            <!-- Main form -->
                            <main class="col-span-12 md:col-span-8">
                                <div class="rounded-2xl border border-white/10 bg-white/5 p-4">
                                    <!-- Compact dropdown nav -->
                                    <div v-if="isCompact" class="mb-3">
                                        <Button
                                            type="button"
                                            class="w-full !border-white/20 !text-slate-100"
                                            icon="pi pi-chevron-down"
                                            iconPos="right"
                                            :label="selectedNav ? selectedNav.label : 'Selecionar seção'"
                                            outlined
                                            @click="toggleNav($event)"
                                        />

                                        <Popover ref="navPopover">
                                            <div class="flex flex-col gap-2 p-1" style="min-width: 260px">
                                                <div class="px-2 pt-2 text-xs font-semibold">Seções</div>
                                                <ul class="m-0 list-none p-2">
                                                    <li v-for="item in navItems" :key="item.value" class="flex cursor-pointer items-center gap-2 rounded-xl px-2 py-2 text-sm hover:bg-black/5" @click="selectNav(item)">
                                                        <i :class="item.icon" style="opacity: 0.85" />
                                                        <span class="font-medium">{{ item.label }}</span>
                                                    </li>
                                                </ul>
                                            </div>
                                        </Popover>
                                    </div>

                                    <Accordion :multiple="false" v-model:value="activeValue">
                                        <!-- 0 -->
                                        <AccordionPanel value="0">
                                            <AccordionHeader :ref="(el) => setPanelHeaderRef(el, 0)"> 1. Informações pessoais </AccordionHeader>
                                            <AccordionContent>
                                                <div class="grid grid-cols-1 gap-4 lg:grid-cols-2">
                                                    <div class="lg:col-span-2">
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-user" />
                                                                <InputText id="f_nome" v-model="form.nome_completo" class="w-full" variant="filled" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_nome">Nome completo *</label>
                                                        </FloatLabel>
                                                        <div v-if="errors.nome_completo" class="mt-2 rounded-xl border border-rose-400/30 bg-rose-400/10 px-3 py-2 text-xs text-rose-100">
                                                            {{ errors.nome_completo }}
                                                        </div>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-mobile" />
                                                                <InputMask id="f_telefone" v-model="form.telefone" class="w-full" variant="filled" mask="(99) 99999-9999" placeholder="(00) 00000-0000" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_telefone">Telefone / WhatsApp *</label>
                                                        </FloatLabel>
                                                        <div v-if="errors.telefone" class="mt-2 rounded-xl border border-rose-400/30 bg-rose-400/10 px-3 py-2 text-xs text-rose-100">
                                                            {{ errors.telefone }}
                                                        </div>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-envelope" />
                                                                <InputText id="f_email_principal" v-model="form.email_principal" class="w-full" variant="filled" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_email_principal">E-mail principal *</label>
                                                        </FloatLabel>
                                                        <div v-if="errors.email_principal" class="mt-2 rounded-xl border border-rose-400/30 bg-rose-400/10 px-3 py-2 text-xs text-rose-100">
                                                            {{ errors.email_principal }}
                                                        </div>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-envelope" />
                                                                <InputText id="f_email_alt" v-model="form.email_alternativo" class="w-full" variant="filled" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_email_alt">E-mail alternativo</label>
                                                        </FloatLabel>
                                                        <div v-if="errors.email_alternativo" class="mt-2 rounded-xl border border-rose-400/30 bg-rose-400/10 px-3 py-2 text-xs text-rose-100">
                                                            {{ errors.email_alternativo }}
                                                        </div>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-phone" />
                                                                <InputMask id="f_tel_alt" v-model="form.telefone_alternativo" class="w-full" variant="filled" mask="(99) 99999?-9999" placeholder="(00) 00000-0000" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_tel_alt">Telefone alternativo</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-calendar" />
                                                                <InputMask id="f_nasc" v-model="form.data_nascimento" mask="99-99-9999" class="w-full" variant="filled" placeholder="DD-MM-AAAA" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_nasc">Data de nascimento</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-venus" />
                                                                <Select id="f_genero" v-model="form.genero" :options="GENDER_OPTIONS" optionLabel="label" optionValue="value" class="w-full pl-[25px]" showClear variant="filled" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_genero">Gênero</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-heart" />
                                                                <Select
                                                                    id="f_estado_civil"
                                                                    v-model="form.estado_civil"
                                                                    :options="MARITAL_OPTIONS"
                                                                    optionLabel="label"
                                                                    optionValue="value"
                                                                    class="w-full pl-[25px]"
                                                                    showClear
                                                                    variant="filled"
                                                                    :disabled="salvando"
                                                                />
                                                            </IconField>
                                                            <label for="f_estado_civil">Estado civil</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-id-card" />
                                                                <InputMask id="f_cpf" v-model="form.cpf" class="w-full" variant="filled" mask="999.999.999-99" placeholder="000.000.000-00" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_cpf">CPF</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-credit-card" />
                                                                <InputMask id="f_rg" v-model="form.rg" class="w-full" variant="filled" mask="99.999.999-9" placeholder="00.000.000-0" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_rg">RG</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-flag" />
                                                                <InputText id="f_nacionalidade" v-model="form.nacionalidade" class="w-full" variant="filled" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_nacionalidade">Nacionalidade</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div class="lg:col-span-2">
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-globe" />
                                                                <InputText id="f_naturalidade" v-model="form.naturalidade" class="w-full" variant="filled" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_naturalidade">Naturalidade</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div class="lg:col-span-2">
                                                        <FloatLabel variant="on">
                                                            <IconField iconPosition="left">
                                                                <InputIcon class="pi pi-comment" />
                                                                <Textarea id="f_observacoes" v-model="form.observacoes" class="w-full" autoResize rows="3" variant="filled" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_observacoes">Observações</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-megaphone" />
                                                                <InputText id="f_onde" v-model="form.onde_nos_conheceu" class="w-full" variant="filled" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_onde">Onde nos conheceu?</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-share-alt" />
                                                                <InputText id="f_encaminhado" v-model="form.encaminhado_por" class="w-full" variant="filled" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_encaminhado">Encaminhado por</label>
                                                        </FloatLabel>
                                                    </div>
                                                </div>
                                            </AccordionContent>
                                        </AccordionPanel>

                                        <!-- 1 -->
                                        <AccordionPanel value="1">
                                            <AccordionHeader :ref="(el) => setPanelHeaderRef(el, 1)"> 2. Endereço </AccordionHeader>
                                            <AccordionContent>
                                                <div class="grid grid-cols-1 gap-4 lg:grid-cols-2">
                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-map-marker" />
                                                                <InputMask id="f_cep" v-model="form.cep" class="w-full" variant="filled" mask="99999-999" placeholder="00000-000" :disabled="salvando" @blur="onCepBlur" @keyup.enter="onCepBlur" />
                                                            </IconField>
                                                            <label for="f_cep">CEP</label>
                                                        </FloatLabel>
                                                        <div v-if="cepLoading" class="mt-2 text-xs text-slate-300">Consultando CEP…</div>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-map-marker" />
                                                                <InputText id="f_pais" v-model="form.pais" class="w-full" variant="filled" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_pais">País</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-map-marker" />
                                                                <InputText id="f_cidade" v-model="form.cidade" class="w-full" variant="filled" :disabled="addressLocked" />
                                                            </IconField>
                                                            <label for="f_cidade">Cidade</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-map-marker" />
                                                                <InputText id="f_estado" v-model="form.estado" class="w-full" variant="filled" :disabled="addressLocked" />
                                                            </IconField>
                                                            <label for="f_estado">Estado</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-map-marker" />
                                                                <InputText id="f_endereco" v-model="form.endereco" class="w-full" variant="filled" :disabled="addressLocked" />
                                                            </IconField>
                                                            <label for="f_endereco">Endereço</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-map-marker" />
                                                                <InputText id="f_numero" v-model="form.numero" class="w-full" variant="filled" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_numero">Número</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-map-marker" />
                                                                <InputText id="f_bairro" v-model="form.bairro" class="w-full" variant="filled" :disabled="addressLocked" />
                                                            </IconField>
                                                            <label for="f_bairro">Bairro</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-map-marker" />
                                                                <InputText id="f_complemento" v-model="form.complemento" class="w-full" variant="filled" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_complemento">Complemento</label>
                                                        </FloatLabel>
                                                    </div>
                                                </div>
                                            </AccordionContent>
                                        </AccordionPanel>

                                        <!-- 2 -->
                                        <AccordionPanel value="2">
                                            <AccordionHeader :ref="(el) => setPanelHeaderRef(el, 2)"> 3. Dados adicionais </AccordionHeader>
                                            <AccordionContent>
                                                <div class="grid grid-cols-1 gap-4 lg:grid-cols-2">
                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-book" />
                                                                <InputText id="f_escolaridade" v-model="form.escolaridade" class="w-full" variant="filled" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_escolaridade">Escolaridade</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-briefcase" />
                                                                <InputText id="f_profissao" v-model="form.profissao" class="w-full" variant="filled" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_profissao">Profissão</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div class="lg:col-span-2">
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-user" />
                                                                <InputText id="f_nome_parente" v-model="form.nome_parente" class="w-full" variant="filled" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_nome_parente">Nome de um parente (opcional)</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-users" />
                                                                <InputText id="f_parentesco" v-model="form.grau_parentesco" class="w-full" variant="filled" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_parentesco">Parentesco</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-phone" />
                                                                <InputMask id="f_tel_parente" v-model="form.telefone_parente" class="w-full" variant="filled" mask="(99) 99999?-9999" placeholder="(00) 00000-0000" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_tel_parente">Telefone do parente</label>
                                                        </FloatLabel>
                                                    </div>
                                                </div>
                                            </AccordionContent>
                                        </AccordionPanel>

                                        <!-- 3 -->
                                        <AccordionPanel value="3">
                                            <AccordionHeader :ref="(el) => setPanelHeaderRef(el, 3)"> 4. Responsável </AccordionHeader>
                                            <AccordionContent>
                                                <div class="grid grid-cols-1 gap-4 lg:grid-cols-2">
                                                    <div class="lg:col-span-2">
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-user" />
                                                                <InputText id="f_nome_responsavel" v-model="form.nome_responsavel" class="w-full" variant="filled" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_nome_responsavel">Nome do responsável</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-id-card" />
                                                                <InputMask id="f_cpf_responsavel" v-model="form.cpf_responsavel" class="w-full" variant="filled" mask="999.999.999-99" placeholder="000.000.000-00" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_cpf_responsavel">CPF do responsável</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div>
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-phone" />
                                                                <InputMask id="f_tel_responsavel" v-model="form.telefone_responsavel" class="w-full" variant="filled" mask="(99) 99999-9999" placeholder="(00) 00000-0000" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_tel_responsavel">Telefone do responsável</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div class="lg:col-span-2">
                                                        <FloatLabel variant="on">
                                                            <IconField>
                                                                <InputIcon class="pi pi-comment" />
                                                                <Textarea id="f_obs_responsavel" v-model="form.observacao_responsavel" class="w-full" autoResize rows="4" variant="filled" :disabled="salvando" />
                                                            </IconField>
                                                            <label for="f_obs_responsavel">Observação do responsável</label>
                                                        </FloatLabel>
                                                    </div>

                                                    <div class="lg:col-span-2">
                                                        <div class="rounded-2xl border border-white/10 bg-white/5 p-4">
                                                            <div class="flex items-start gap-3">
                                                                <Checkbox v-model="form.cobranca_no_responsavel" :binary="true" inputId="f_cobranca_no_responsavel" :disabled="salvando" />
                                                                <label for="f_cobranca_no_responsavel" class="text-sm text-slate-200">
                                                                    Permitir o envio de cobranças no nome do responsável?
                                                                    <span class="block pt-1 text-xs text-slate-300"> O sistema poderá usar nome e CPF do responsável nas cobranças. </span>
                                                                </label>
                                                            </div>
                                                        </div>
                                                    </div>
                                                </div>
                                            </AccordionContent>
                                        </AccordionPanel>

                                    </Accordion>

                                    <!-- Footer / Consent + CTA -->
                                    <div class="mt-5 flex flex-col gap-3">
                                        <div class="rounded-2xl border border-white/10 bg-white/5 p-4">
                                            <div class="flex items-start gap-3">
                                                <Checkbox v-model="consent" :binary="true" :disabled="salvando" inputId="ext_consent" />
                                                <div class="min-w-0">
                                                    <label for="ext_consent" class="block text-sm font-semibold text-slate-100"> Concordo em enviar meus dados para o terapeuta. </label>
                                                    <div class="mt-1 text-xs text-slate-300">
                                                        Seus dados serão usados apenas para contato e organização do atendimento.
                                                        <button type="button" class="ml-1 underline text-emerald-300 hover:text-emerald-200 focus:outline-none" @click="policyOpen = true">
                                                            Ver política de privacidade
                                                        </button>
                                                    </div>

                                                    <div v-if="errors.consentimento" class="mt-2 rounded-xl border border-rose-400/30 bg-rose-400/10 px-3 py-2 text-xs text-rose-100">
                                                        {{ errors.consentimento }}
                                                    </div>
                                                </div>
                                            </div>
                                        </div>

                                        <!-- A#20 rev2: HONEYPOT invisível — bot preenche tudo, humano nunca vê -->
                                        <div class="absolute -left-[9999px]" aria-hidden="true">
                                            <label for="ext_website">Não preencha este campo</label>
                                            <input
                                                id="ext_website"
                                                v-model="honeypot"
                                                type="text"
                                                tabindex="-1"
                                                autocomplete="off"
                                            />
                                        </div>

                                        <!-- A#20 rev2: math captcha CONDICIONAL — só aparece quando edge pedir -->
                                        <MathCaptchaChallenge
                                            v-if="captchaRequired"
                                            v-model:id="captchaId"
                                            v-model:answer="captchaAnswer"
                                        />

                                        <div class="flex flex-col gap-2 md:flex-row md:items-center md:justify-between">
                                            <div class="text-xs text-slate-300">Se algo falhar, peça um novo link ao terapeuta.</div>

                                            <Button
                                                label="Enviar cadastro"
                                                icon="pi pi-send"
                                                class="!bg-emerald-400/90 !border-emerald-400/50 !text-slate-950 md:!min-w-[240px]"
                                                :loading="salvando"
                                                :disabled="salvando || sucesso || !tokenOk || (captchaRequired && (!captchaId || captchaAnswer == null))"
                                                @click="enviar"
                                            />
                                        </div>
                                    </div>
                                </div>
                            </main>
                        </div>
                    </div>
                </div>

                <!-- subtle footer -->
                <div class="mt-4 text-center text-xs text-slate-400">Ao enviar, você confirma que está fornecendo informações verdadeiras e que autoriza o contato.</div>
            </div>
        </div>

        <!-- A#25: Política de privacidade (dialog inline) -->
        <Dialog
            v-model:visible="policyOpen"
            modal
            header="Política de privacidade"
            :style="{ width: '92vw', maxWidth: '720px' }"
            :breakpoints="{ '640px': '96vw' }"
            :draggable="false"
            :dismissableMask="true"
        >
            <div class="text-sm leading-relaxed text-[var(--text-color)] space-y-4">
                <section>
                    <h3 class="text-base font-semibold">Finalidade do tratamento</h3>
                    <p>Seus dados pessoais são coletados exclusivamente para viabilizar o contato do terapeuta com você e organizar o atendimento clínico. Não são usados para marketing, compartilhamento com terceiros ou perfilamento.</p>
                </section>

                <section>
                    <h3 class="text-base font-semibold">Dados coletados</h3>
                    <ul class="list-disc pl-5 space-y-1">
                        <li>Identificação: nome completo, CPF, RG (opcional), data de nascimento, gênero, estado civil, nacionalidade, naturalidade.</li>
                        <li>Contato: telefone(s), e-mail(s), endereço.</li>
                        <li>Contexto: profissão, escolaridade, parente/responsável, origem do contato, observações que você optar por fornecer.</li>
                    </ul>
                </section>

                <section>
                    <h3 class="text-base font-semibold">Base legal (LGPD)</h3>
                    <p>Tratamos seus dados com base no <b>consentimento</b> que você fornece ao marcar a caixa correspondente (Art. 7º, I da Lei 13.709/2018), e quando aplicável, também com base na execução de contrato de prestação de serviço terapêutico (Art. 7º, V).</p>
                </section>

                <section>
                    <h3 class="text-base font-semibold">Retenção</h3>
                    <p>Dados de pré-cadastro são mantidos pelo tempo necessário para a conversão em paciente (ou descarte, se não houver andamento). Após início do vínculo terapêutico, seguem as regras aplicáveis ao prontuário clínico (Resolução CFP 001/2009: no mínimo 5 anos após último atendimento).</p>
                </section>

                <section>
                    <h3 class="text-base font-semibold">Seus direitos</h3>
                    <p>A qualquer momento você pode solicitar, sem custo:</p>
                    <ul class="list-disc pl-5 space-y-1">
                        <li>Confirmação da existência de tratamento;</li>
                        <li>Acesso aos seus dados;</li>
                        <li>Correção de dados incompletos, inexatos ou desatualizados;</li>
                        <li>Anonimização, bloqueio ou eliminação de dados desnecessários;</li>
                        <li>Portabilidade dos dados;</li>
                        <li>Eliminação dos dados pessoais tratados com base no consentimento;</li>
                        <li>Revogação do consentimento.</li>
                    </ul>
                    <p class="mt-2">Para exercer qualquer desses direitos, entre em contato diretamente com o profissional que enviou este link.</p>
                </section>

                <section>
                    <h3 class="text-base font-semibold">Segurança</h3>
                    <p>Adotamos medidas técnicas (criptografia em trânsito, controle de acesso, registros de auditoria) e administrativas para proteger seus dados. Ainda assim, nenhum sistema é 100% seguro — comprometa apenas o estritamente necessário.</p>
                </section>

                <section class="text-xs text-[var(--text-color-secondary)]">
                    <p>Esta política pode ser atualizada. Data da última revisão: 18/04/2026.</p>
                </section>
            </div>

            <template #footer>
                <Button label="Entendi" icon="pi pi-check" @click="policyOpen = false" />
            </template>
        </Dialog>
    </div>
</template>
