<!--
|--------------------------------------------------------------------------
| Agência PSI — Editor de telefones polimórfico
|--------------------------------------------------------------------------
| Uso:
|   <ContactPhonesEditor entity-type="patient" :entity-id="patient.id" />
|
| Auto-salva mudanças no banco (contact_phones) via useContactPhones.
|--------------------------------------------------------------------------
-->
<script setup>
import { ref, computed, onMounted, watch, reactive } from 'vue';
import { useToast } from 'primevue/usetoast';
import { useConfirm } from 'primevue/useconfirm';
import { useContactPhones } from '@/composables/useContactPhones';

const props = defineProps({
    entityType: { type: String, required: true },   // 'patient' | 'medico'
    entityId: { type: String, required: false, default: null },  // null = modo pendente (antes de criar entidade)
    readonly: { type: Boolean, default: false },
    confirmGroup: { type: String, default: '' }      // grupo do ConfirmDialog (pra isolar de outros na página)
});

const emit = defineEmits(['change']);

const toast = useToast();
const confirm = useConfirm();
const api = useContactPhones();

// ── Mascaras ─────────────────────────────────────────────────
const MASK_MOBILE = '(99) 99999-9999';
const MASK_FIXED = '(99) 9999-9999';

function maskForType(typeId) {
    const t = api.typeById(typeId);
    return t?.is_mobile ? MASK_MOBILE : MASK_FIXED;
}

// ── Formulário de nova linha ─────────────────────────────────
const showAddForm = ref(false);
const newForm = reactive({ contact_type_id: null, number: '', notes: '' });

function openAddForm() {
    // Default: primeiro tipo system (celular)
    const defaultType = api.typeBySlug('celular') || api.types.value[0];
    newForm.contact_type_id = defaultType?.id || null;
    newForm.number = '';
    newForm.notes = '';
    showAddForm.value = true;
}

function cancelAddForm() {
    showAddForm.value = false;
}

async function submitAddForm() {
    if (!newForm.contact_type_id || !newForm.number.trim()) return;
    const res = await api.addPhone(props.entityType, props.entityId, {
        contact_type_id: newForm.contact_type_id,
        number: newForm.number,
        is_primary: api.phones.value.length === 0, // primeiro vira primary
        notes: newForm.notes || null
    });
    if (res.ok) {
        showAddForm.value = false;
        toast.add({ severity: 'success', summary: 'Telefone adicionado', life: 1800 });
        emit('change', api.phones.value);
    } else {
        toast.add({ severity: 'error', summary: 'Erro', detail: res.error, life: 3500 });
    }
}

// ── Edição inline ────────────────────────────────────────────
const editingId = ref(null);
const editForm = reactive({ contact_type_id: null, number: '', notes: '' });

function startEdit(phone) {
    editingId.value = phone.id;
    editForm.contact_type_id = phone.contact_type_id;
    editForm.number = phone.number;
    editForm.notes = phone.notes || '';
}

function cancelEdit() {
    editingId.value = null;
}

async function saveEdit(phone) {
    const res = await api.updatePhone(props.entityType, props.entityId, phone.id, {
        contact_type_id: editForm.contact_type_id,
        number: editForm.number,
        notes: editForm.notes.trim() || null
    });
    if (res.ok) {
        editingId.value = null;
        toast.add({ severity: 'success', summary: 'Telefone atualizado', life: 1800 });
        emit('change', api.phones.value);
    } else {
        toast.add({ severity: 'error', summary: 'Erro', detail: res.error, life: 3500 });
    }
}

// ── Principal ────────────────────────────────────────────────
async function setPrimary(phone) {
    if (phone.is_primary) return;
    const res = await api.setPrimary(props.entityType, props.entityId, phone.id);
    if (res.ok) {
        toast.add({ severity: 'success', summary: 'Telefone principal atualizado', life: 1800 });
        emit('change', api.phones.value);
    }
}

// ── Remover ──────────────────────────────────────────────────
function confirmRemove(phone) {
    const typeName = api.typeById(phone.contact_type_id)?.name || 'telefone';
    confirm.require({
        group: props.confirmGroup || undefined,
        message: `Remover este ${typeName}${phone.is_primary ? ' (principal)' : ''}?`,
        header: 'Remover telefone',
        icon: 'pi pi-exclamation-triangle',
        acceptClass: 'p-button-danger',
        acceptLabel: 'Remover',
        rejectLabel: 'Cancelar',
        accept: async () => {
            const res = await api.removePhone(props.entityType, props.entityId, phone.id);
            if (res.ok) {
                toast.add({ severity: 'success', summary: 'Removido', life: 1800 });
                emit('change', api.phones.value);
            } else {
                toast.add({ severity: 'error', summary: 'Erro', detail: res.error, life: 3500 });
            }
        }
    });
}

// ── Helpers ──────────────────────────────────────────────────
function formatDisplay(number) {
    const s = String(number || '').replace(/\D/g, '');
    if (s.length === 11) return `(${s.slice(0, 2)}) ${s.slice(2, 7)}-${s.slice(7)}`;
    if (s.length === 10) return `(${s.slice(0, 2)}) ${s.slice(2, 6)}-${s.slice(6)}`;
    if (s.length === 13 && s.startsWith('55')) return `+55 (${s.slice(2, 4)}) ${s.slice(4, 9)}-${s.slice(9)}`;
    if (s.length === 12 && s.startsWith('55')) return `+55 (${s.slice(2, 4)}) ${s.slice(4, 8)}-${s.slice(8)}`;
    return number;
}

// ── Lifecycle ────────────────────────────────────────────────
onMounted(async () => {
    await api.loadTypes();
    if (props.entityId) await api.loadPhones(props.entityType, props.entityId);
});

watch(() => props.entityId, async (v) => {
    if (v) await api.loadPhones(props.entityType, v);
    else api.phones.value = [];
});

// Re-emite `change` sempre que a lista mudar (load, add, edit, remove,
// setPrimary). Permite que o parent trackee count e faça validação de
// "pelo menos 1 telefone obrigatório" sem precisar inspeccionar o
// componente. immediate:true garante emit no load inicial.
watch(api.phones, (arr) => emit('change', arr), { deep: true, immediate: true });

// Exposto pro parent — usado pelo PatientsCadastroPage no fluxo de criação:
// telefones inseridos antes de salvar o paciente ficam em modo pendente
// (id: 'pending_*') e são gravados em lote depois que o paciente recebe id.
async function flushPending(entityType, entityId) {
    return api.flushPending(entityType, entityId);
}
defineExpose({ flushPending });
</script>

<template>
    <div class="flex flex-col gap-2">
        <!-- Lista de telefones -->
        <div v-if="api.loading.value" class="text-xs text-center py-3 text-[var(--text-color-secondary)]">
            <i class="pi pi-spin pi-spinner mr-1" /> Carregando…
        </div>

        <div v-else-if="!api.phones.value.length && !showAddForm" class="text-xs text-center py-4 italic text-[var(--text-color-secondary)] border border-dashed border-[var(--surface-border)] rounded-md">
            Nenhum telefone cadastrado.
        </div>

        <div v-else class="flex flex-col gap-1.5">
            <div
                v-for="phone in api.phones.value"
                :key="phone.id"
                class="flex items-center gap-2 p-2 rounded-md border border-[var(--surface-border)]"
                :class="phone.is_primary ? 'bg-[var(--primary-color)]/5 border-[var(--primary-color)]/30' : 'bg-[var(--surface-card)]'"
            >
                <!-- Modo leitura -->
                <template v-if="editingId !== phone.id">
                    <!-- Ícone do tipo -->
                    <div class="w-8 h-8 rounded grid place-items-center shrink-0 bg-[var(--surface-ground)]">
                        <i :class="api.typeById(phone.contact_type_id)?.icon || 'pi pi-phone'" class="text-sm text-[var(--text-color-secondary)]" />
                    </div>

                    <!-- Tipo + número + badges -->
                    <div class="flex-1 min-w-0 flex flex-col gap-0.5">
                        <div class="flex items-center gap-1.5 flex-wrap">
                            <span class="text-xs font-semibold text-[var(--text-color-secondary)]">{{ api.typeById(phone.contact_type_id)?.name || 'Telefone' }}</span>
                            <span v-if="phone.is_primary" class="inline-flex items-center px-1.5 py-px rounded-full text-[0.6rem] font-bold uppercase tracking-wide bg-[var(--primary-color)] text-white">Principal</span>
                            <span v-if="phone.whatsapp_linked_at" class="inline-flex items-center gap-0.5 px-1.5 py-px rounded-full text-[0.6rem] font-bold uppercase tracking-wide bg-emerald-500/15 text-emerald-600">
                                <i class="pi pi-link text-[0.55rem]" /> Vinculado
                            </span>
                        </div>
                        <span class="text-sm font-mono font-semibold">{{ formatDisplay(phone.number) }}</span>
                        <span v-if="phone.notes" class="text-[0.7rem] italic text-[var(--text-color-secondary)]">{{ phone.notes }}</span>
                    </div>

                    <!-- Ações -->
                    <div v-if="!readonly" class="flex items-center gap-0.5 shrink-0">
                        <Button
                            v-if="!phone.is_primary"
                            icon="pi pi-star"
                            text
                            size="small"
                            class="h-7 w-7"
                            v-tooltip.top="'Marcar como principal'"
                            :disabled="api.saving.value"
                            @click="setPrimary(phone)"
                        />
                        <Button
                            icon="pi pi-pencil"
                            text
                            size="small"
                            class="h-7 w-7"
                            v-tooltip.top="'Editar'"
                            :disabled="api.saving.value"
                            @click="startEdit(phone)"
                        />
                        <Button
                            icon="pi pi-trash"
                            text
                            severity="danger"
                            size="small"
                            class="h-7 w-7"
                            v-tooltip.top="'Remover'"
                            :disabled="api.saving.value"
                            @click="confirmRemove(phone)"
                        />
                    </div>
                </template>

                <!-- Modo edição -->
                <template v-else>
                    <div class="flex flex-col gap-1.5 flex-1 min-w-0">
                        <div class="flex items-center gap-1.5 flex-wrap">
                            <Select
                                v-model="editForm.contact_type_id"
                                :options="api.types.value"
                                optionLabel="name"
                                optionValue="id"
                                class="text-xs"
                                style="width: 140px"
                                appendTo="body"
                            >
                                <template #option="slotProps">
                                    <div class="flex items-center gap-1.5">
                                        <i :class="slotProps.option.icon || 'pi pi-phone'" class="text-xs" />
                                        <span>{{ slotProps.option.name }}</span>
                                    </div>
                                </template>
                            </Select>
                            <InputMask
                                v-model="editForm.number"
                                :mask="maskForType(editForm.contact_type_id)"
                                class="flex-1 text-sm font-mono"
                                style="min-width: 140px"
                            />
                        </div>
                        <InputText
                            v-model="editForm.notes"
                            placeholder="Observação (opcional)"
                            class="w-full text-xs"
                            :maxlength="200"
                        />
                    </div>
                    <div class="flex items-center gap-0.5 shrink-0">
                        <Button icon="pi pi-check" severity="primary" size="small" class="h-7 w-7" v-tooltip.top="'Salvar'" :loading="api.saving.value" @click="saveEdit(phone)" />
                        <Button icon="pi pi-times" severity="secondary" text size="small" class="h-7 w-7" v-tooltip.top="'Cancelar'" :disabled="api.saving.value" @click="cancelEdit" />
                    </div>
                </template>
            </div>
        </div>

        <!-- Formulário de nova linha -->
        <div v-if="showAddForm" class="flex flex-col gap-2 p-2 rounded-md border border-dashed border-[var(--primary-color)]/50 bg-[var(--primary-color)]/5">
            <div class="flex items-center gap-1.5 flex-wrap">
                <Select
                    v-model="newForm.contact_type_id"
                    :options="api.types.value"
                    optionLabel="name"
                    optionValue="id"
                    class="text-xs"
                    style="width: 140px"
                    appendTo="body"
                >
                    <template #option="slotProps">
                        <div class="flex items-center gap-1.5">
                            <i :class="slotProps.option.icon || 'pi pi-phone'" class="text-xs" />
                            <span>{{ slotProps.option.name }}</span>
                        </div>
                    </template>
                </Select>
                <InputMask
                    v-model="newForm.number"
                    :mask="maskForType(newForm.contact_type_id)"
                    class="flex-1 text-sm font-mono"
                    style="min-width: 140px"
                    autofocus
                />
            </div>
            <InputText
                v-model="newForm.notes"
                placeholder="Observação (opcional)"
                class="w-full text-xs"
                :maxlength="200"
            />
            <div class="flex items-center gap-1 justify-end">
                <Button label="Cancelar" severity="secondary" text size="small" :disabled="api.saving.value" @click="cancelAddForm" />
                <Button
                    label="Adicionar"
                    icon="pi pi-check"
                    size="small"
                    :loading="api.saving.value"
                    :disabled="!newForm.contact_type_id || !newForm.number.trim()"
                    @click="submitAddForm"
                />
            </div>
        </div>

        <!-- Botão + (sempre habilitado: sem entityId vai pro modo pendente) -->
        <Button
            v-if="!readonly && !showAddForm"
            label="Adicionar telefone"
            icon="pi pi-plus"
            severity="secondary"
            outlined
            size="small"
            class="self-start rounded-full"
            @click="openAddForm"
        />
    </div>
</template>
