<!--
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/components/ComponentCadastroRapido.vue
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
-->
<script setup>
import { computed, reactive, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useRoleGuard } from '@/composables/useRoleGuard';
import { isValidEmail, isValidPhone, sanitizeDigits } from '@/utils/validators';

import { useToast } from 'primevue/usetoast';
import { maybeShowPlanLimitToast } from '@/utils/planLimit';

import InputMask from 'primevue/inputmask';
import Message from 'primevue/message';

// Audit alta (2026-05-20): substituir supabase direto por repository pattern.
import { usePatients } from '@/features/patients/composables/usePatients';
import { getMyActiveMember } from '@/features/tenantship/services/tenantMembersRepository';
const { canSee } = useRoleGuard();
const route = useRoute();
const router = useRouter();
const patientsStore = usePatients();

const isOnPatientsPage = computed(() => {
    const p = String(route.path || '');
    return p.includes('/patients') || p.includes('/pacientes');
});

/**
 * Lista "curada" de pensadores influentes na psicanálise e seu entorno.
 * Usada para geração rápida de dados fictícios.
 */
const PSICANALISE_PENSADORES = Object.freeze([
    { nome: 'Sigmund Freud' },
    { nome: 'Jacques Lacan' },
    { nome: 'Melanie Klein' },
    { nome: 'Donald Winnicott' },
    { nome: 'Wilfred Bion' },
    { nome: 'Sándor Ferenczi' },
    { nome: 'Anna Freud' },
    { nome: 'Karl Abraham' },
    { nome: 'Otto Rank' },
    { nome: 'Karen Horney' },
    { nome: 'Erich Fromm' },
    { nome: 'Michael Balint' },
    { nome: 'Ronald Fairbairn' },
    { nome: 'John Bowlby' },
    { nome: 'André Green' },
    { nome: 'Jean Laplanche' },
    { nome: 'Christopher Bollas' },
    { nome: 'Thomas Ogden' },
    { nome: 'Jessica Benjamin' },
    { nome: 'Joyce McDougall' },
    { nome: 'Peter Fonagy' },
    { nome: 'Carl Gustav Jung' },
    { nome: 'Alfred Adler' }
]);

// domínio seguro para dados fictícios
const AUTO_EMAIL_DOMAIN = 'example.com';

const props = defineProps({
    modelValue: { type: Boolean, default: false },
    title: { type: String, default: 'Cadastro rápido' },

    tableName: { type: String, default: 'patients' },
    ownerField: { type: String, default: 'owner_id' },

    // defaults alinhados com seu schema
    nameField: { type: String, default: 'nome_completo' },
    emailField: { type: String, default: 'email_principal' },
    phoneField: { type: String, default: 'telefone' },

    // multi-tenant (defaults do seu schema)
    tenantField: { type: String, default: 'tenant_id' },
    responsibleMemberField: { type: String, default: 'responsible_member_id' },

    extraPayload: { type: Object, default: () => ({}) },

    // Pré-preenchimento (usado ao converter número desconhecido em paciente, etc)
    initialData: { type: Object, default: () => ({}) },

    closeOnCreated: { type: Boolean, default: true },
    resetOnOpen: { type: Boolean, default: true },

    // Quando true (uso "in-flow", ex: dentro do AgendaEventDialog),
    // esconde o botao "Salvar e ver pacientes" — navegar pra lista
    // abandonaria o fluxo onde o cadastro foi aberto. Default false
    // mantem o botao visivel pra usos standalone (sidebar, menu).
    hideViewListButton: { type: Boolean, default: false }
});

const emit = defineEmits(['update:modelValue', 'created']);
const toast = useToast();

const saving = ref(false);
const touched = ref(false);
const errorMsg = ref('');

const form = reactive({
    nome_completo: '',
    email_principal: '',
    telefone: ''
});

const isOpen = computed({
    get: () => props.modelValue,
    set: (v) => emit('update:modelValue', v)
});

watch(
    () => props.modelValue,
    (v) => {
        if (v && props.resetOnOpen) reset();
        if (v) {
            touched.value = false;
            errorMsg.value = '';
        }
    }
);

function reset() {
    const init = props.initialData || {};
    form.nome_completo = init.nome_completo ?? '';
    form.email_principal = init.email_principal ?? '';
    form.telefone = init.telefone ?? '';
}

function close() {
    isOpen.value = false;
}

function onHide() {}

function normalizePhoneDigits(v) {
    return sanitizeDigits(v);
}

/* ----------------------------
 * Gerador (nome/email/telefone)
 * ---------------------------- */
function randInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}
function pick(arr) {
    return arr[randInt(0, arr.length - 1)];
}
function slugify(s) {
    return String(s || '')
        .normalize('NFD')
        .replace(/[\u0300-\u036f]/g, '')
        .toLowerCase()
        .replace(/[^a-z0-9]+/g, '.')
        .replace(/(^\.)|(\.$)/g, '');
}
function randomPhoneBRMasked() {
    const ddd = randInt(11, 99);
    const a = randInt(10000, 99999);
    const b = randInt(1000, 9999);
    return `(${ddd}) ${a}-${b}`;
}

function generateUser() {
    if (saving.value) return;

    const p = pick(PSICANALISE_PENSADORES);
    const nome = p?.nome || 'Paciente';

    const base = slugify(nome) || 'paciente';
    const suffix = randInt(10, 999);
    const email = `${base}.${suffix}@${AUTO_EMAIL_DOMAIN}`;

    form.nome_completo = nome;
    form.email_principal = email;
    form.telefone = randomPhoneBRMasked();

    touched.value = true;
    errorMsg.value = '';

    toast.add({
        severity: 'info',
        summary: 'Gerar usuário',
        detail: 'Dados fictícios preenchidos.',
        life: 2200
    });
}

// Rota de destino do "Salvar e ver paciente". Em melissa, prefere a
// view individual do paciente recém-criado (id vem de data.id no
// emit('created')); fallback pra lista.
function patientViewRoute(patientId) {
    const p = String(route.path || '');
    if (p.startsWith('/melissa') && patientId) {
        return { path: '/melissa/paciente', query: { id: String(patientId) } };
    }
    if (p.startsWith('/melissa')) {
        return '/melissa/pacientes';
    }
    return p.startsWith('/therapist') ? '/therapist/patients' : '/admin/pacientes';
}

async function submit(mode = 'only') {
    touched.value = true;
    errorMsg.value = '';

    const nome = String(form.nome_completo || '').trim();
    const email = String(form.email_principal || '').trim();
    const tel = String(form.telefone || '');

    if (!nome) return;
    if (!email) return;
    if (!isValidEmail(email)) return;
    if (!tel) return;
    if (!isValidPhone(tel)) return;

    saving.value = true;
    try {
        // Resolve tenant_member ativo via repository (audit: não mais supabase direto)
        const member = await getMyActiveMember();
        if (!member?.id || !member?.tenant_id) {
            throw new Error('Responsible member not found');
        }

        // Payload canônico — campos hardcoded da tabela patients.
        // Props deprecated (tableName/ownerField/etc) são ignoradas internamente.
        // owner_id é injetado pelo repository (auth.uid()) — não passamos aqui.
        // extraPayload pode trazer status, observações, etc.
        const payload = {
            ...props.extraPayload,
            tenant_id: member.tenant_id,
            responsible_member_id: member.id,
            nome_completo: nome,
            email_principal: email.toLowerCase(),
            telefone: normalizePhoneDigits(tel)
        };

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

        const data = await patientsStore.create(payload);

        toast.add({
            severity: 'success',
            summary: 'Paciente criado',
            detail: nome,
            life: 2500
        });

        emit('created', data);
        if (props.closeOnCreated) close();
        if (mode === 'view') {
            const pid = data?.id || null;
            await router.push(patientViewRoute(pid));
        }
    } catch (err) {
        const msg = err?.message || err?.details || 'Não foi possível criar o paciente.';
        errorMsg.value = msg;

        if (!maybeShowPlanLimitToast(toast, err, route.fullPath)) {
            toast.add({
                severity: 'error',
                summary: 'Erro ao salvar',
                detail: msg,
                life: 4500
            });
        }

        console.error('[ComponentCadastroRapido] insert error:', err);
    } finally {
        saving.value = false;
    }
}
</script>

<template>
    <Dialog v-model:visible="isOpen" modal :draggable="false" :closable="!saving" :dismissableMask="!saving" :style="{ width: '34rem', maxWidth: '92vw' }" pt:mask:class="backdrop-blur-xs" @hide="onHide">
        <template #header>
            <div class="flex flex-col gap-2">
                <div class="flex items-start justify-between gap-3">
                    <div class="min-w-0">
                        <div class="text-xl font-semibold">{{ title }}</div>
                        <div class="text-sm text-surface-500">Crie um paciente rapidamente.</div>
                    </div>

                    <!-- TOPBAR ACTION -->
                    <Button v-if="canSee('testMODE')" label="Gerar usuário" icon="pi pi-user-plus" severity="secondary" outlined :disabled="saving" @click="generateUser" />
                </div>
            </div>
        </template>

        <div class="flex flex-col gap-3">
            <Message v-if="errorMsg" severity="error" :closable="false">
                {{ errorMsg }}
            </Message>

            <div class="flex flex-col gap-2 mt-2">
                <!-- Nome -->
                <FloatLabel variant="on">
                    <IconField>
                        <InputIcon class="pi pi-user" />
                        <InputText id="cr-nome" v-model.trim="form.nome_completo" class="w-full" variant="filled" :disabled="saving" autocomplete="off" autofocus @keydown.enter.prevent="submit('only')" />
                    </IconField>
                    <label for="cr-nome">Nome completo *</label>
                </FloatLabel>
            </div>

            <div class="flex flex-col gap-2">
                <!-- E-mail -->
                <FloatLabel variant="on">
                    <IconField>
                        <InputIcon class="pi pi-envelope" />
                        <InputText id="cr-email" v-model.trim="form.email_principal" class="w-full" variant="filled" :disabled="saving" inputmode="email" autocomplete="off" @keydown.enter.prevent="submit('only')" />
                    </IconField>
                    <label for="cr-email">E-mail *</label>
                </FloatLabel>
            </div>

            <div class="flex flex-col gap-2">
                <!-- Telefone -->
                <FloatLabel variant="on">
                    <IconField>
                        <InputIcon class="pi pi-phone" />
                        <InputMask id="cr-telefone" v-model="form.telefone" mask="(99) 99999-9999" class="w-full" variant="filled" :disabled="saving" @keydown.enter.prevent="submit('only')" />
                    </IconField>
                    <label for="cr-telefone">Telefone *</label>
                </FloatLabel>
            </div>

            <div class="text-xs text-surface-500">Dica: "Gerar usuário" preenche automaticamente com dados fictícios.</div>
        </div>

        <template #footer>
            <div class="flex justify-end gap-2">
                <Button label="Cancelar" severity="secondary" text :disabled="saving" @click="close" />
                <!-- Na rota de pacientes OU em fluxo (hideViewListButton): só "Salvar" / "Salvar e fechar" -->
                <Button v-if="isOnPatientsPage" label="Salvar" :loading="saving" :disabled="saving" @click="submit('only')" />
                <Button v-else-if="hideViewListButton" label="Salvar e fechar" :loading="saving" :disabled="saving" @click="submit('only')" />
                <!-- Standalone fora da lista: "Salvar e fechar" + "Salvar e ver paciente" -->
                <template v-else>
                    <Button label="Salvar e fechar" severity="secondary" outlined :loading="saving" :disabled="saving" @click="submit('only')" />
                    <Button label="Salvar e ver paciente" :loading="saving" :disabled="saving" @click="submit('view')" />
                </template>
            </div>
        </template>
    </Dialog>
</template>
