<!--
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/layout/configuracoes/ConfiguracoesWhatsappTemplatesPage.vue
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
-->
<script setup>
import { ref, onMounted, nextTick } from 'vue';
import { useToast } from 'primevue/usetoast';
import { useConfirm } from 'primevue/useconfirm';
import { supabase } from '@/lib/supabase/client';
import { tenantDb } from '@/lib/supabase/tenantClient';
import { useTenantStore } from '@/stores/tenantStore';
import { useConversationDrawerStore } from '@/stores/conversationDrawerStore';

const toast = useToast();
const confirm = useConfirm();
const tenantStore = useTenantStore();
const drawerStore = useConversationDrawerStore();

const userId = ref(null);
const tenantId = ref(null);

const templates = ref([]);
const loading = ref(true);
const saving = ref({});
const reverting = ref({});

const EVENT_TYPE_LABELS = {
    lembrete_sessao: 'Lembrete de sessão',
    confirmacao_sessao: 'Confirmação de sessão',
    cancelamento_sessao: 'Cancelamento de sessão',
    reagendamento: 'Reagendamento',
    cobranca_pendente: 'Cobrança pendente',
    boas_vindas_paciente: 'Boas-vindas ao paciente',
    intake_recebido: 'Triagem recebida',
    intake_aprovado: 'Triagem aprovada',
    intake_rejeitado: 'Triagem rejeitada'
};
const EVENT_SEVERITY = {
    lembrete_sessao: 'info',
    confirmacao_sessao: 'success',
    cancelamento_sessao: 'danger',
    reagendamento: 'warn',
    cobranca_pendente: 'warn',
    boas_vindas_paciente: 'success',
    intake_recebido: 'info',
    intake_aprovado: 'success',
    intake_rejeitado: 'danger'
};
const DOMAIN_LABEL = { session: 'Sessão', intake: 'Triagem', billing: 'Financeiro', system: 'Sistema' };

const textareaRefs = ref({});
function setTextareaRef(key, el) {
    if (el) textareaRefs.value[key] = el;
}

async function loadUser() {
    const {
        data: { user }
    } = await supabase.auth.getUser();
    if (!user) return;
    userId.value = user.id;
    tenantId.value = tenantStore.activeTenantId || user.id;
}

async function loadTemplates() {
    if (!tenantId.value) return;
    loading.value = true;
    try {
        const { data: globals, error: gErr } = await tenantDb().from('notification_templates')
            .select('*')
            .eq('channel', 'whatsapp')
            .eq('is_default', true)
            .eq('is_active', true)
            .is('deleted_at', null)
            .order('domain')
            .order('event_type');
        if (gErr) throw gErr;

        const { data: customs, error: cErr } = await tenantDb().from('notification_templates')
            .select('*')
            
            .eq('channel', 'whatsapp')
            .is('deleted_at', null);
        if (cErr) throw cErr;

        const customMap = {};
        for (const c of customs || []) customMap[c.key] = c;

        templates.value = (globals || []).map((g) => {
            const custom = customMap[g.key];
            const current = custom?.body_text ?? g.body_text;
            return {
                key: g.key,
                domain: g.domain,
                event_type: g.event_type,
                label: EVENT_TYPE_LABELS[g.event_type] || g.event_type,
                type_severity: EVENT_SEVERITY[g.event_type] || 'secondary',
                domain_label: DOMAIN_LABEL[g.domain] || g.domain,
                variables: Array.isArray(g.variables) ? g.variables : [],
                default_body: g.body_text,
                id: custom?.id || null,
                body_text: current,
                saved_body: current,
                is_custom: !!custom
            };
        });
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro ao carregar templates', detail: e.message, life: 4000 });
    } finally {
        loading.value = false;
    }
}

function insertVariable(key, variable) {
    const snippet = `{{${variable}}}`;
    const tpl = templates.value.find((t) => t.key === key);
    if (!tpl) return;

    const taWrapper = textareaRefs.value[key];
    const ta = taWrapper?.$el?.querySelector('textarea') ?? taWrapper;
    if (ta?.setSelectionRange) {
        const start = ta.selectionStart ?? ta.value.length;
        const end = ta.selectionEnd ?? start;
        tpl.body_text = (tpl.body_text || '').slice(0, start) + snippet + (tpl.body_text || '').slice(end);
        nextTick(() => {
            const pos = start + snippet.length;
            ta.focus();
            ta.setSelectionRange(pos, pos);
        });
    } else {
        tpl.body_text = (tpl.body_text || '') + snippet;
    }
}

async function saveTemplate(tpl) {
    if (!tenantId.value || saving.value[tpl.key]) return;
    const body = (tpl.body_text || '').trim();
    if (!body) {
        toast.add({ severity: 'warn', summary: 'Mensagem não pode ficar vazia', life: 3000 });
        return;
    }
    if (body.length > 4096) {
        toast.add({ severity: 'warn', summary: 'Mensagem muito longa (máx. 4096 caracteres)', life: 3000 });
        return;
    }

    saving.value[tpl.key] = true;
    try {
        if (tpl.id) {
            const { error } = await tenantDb().from('notification_templates').update({ body_text: body }).eq('id', tpl.id);
            if (error) throw error;
        } else {
            const { data: existing } = await tenantDb().from('notification_templates').select('id').eq('key', tpl.key).is('deleted_at', null).maybeSingle();

            if (existing?.id) {
                const { error } = await tenantDb().from('notification_templates').update({ body_text: body, is_active: true }).eq('id', existing.id);
                if (error) throw error;
                tpl.id = existing.id;
            } else {
                const { data, error } = await tenantDb().from('notification_templates')
                    .insert({
                        owner_id: userId.value,
                        channel: 'whatsapp',
                        key: tpl.key,
                        domain: tpl.domain,
                        event_type: tpl.event_type,
                        body_text: body,
                        variables: tpl.variables,
                        is_active: true,
                        is_default: false
                    })
                    .select('id')
                    .single();
                if (error) throw error;
                tpl.id = data.id;
            }
            tpl.is_custom = true;
        }
        tpl.saved_body = body;
        tpl.body_text = body;
        drawerStore.invalidateTemplates();
        toast.add({ severity: 'success', summary: 'Template salvo', life: 3000 });
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro ao salvar', detail: e.message, life: 5000 });
    } finally {
        saving.value[tpl.key] = false;
    }
}

function confirmRevert(tpl) {
    if (!tpl.is_custom || !tpl.id) return;
    confirm.require({
        group: 'headless',
        message: `Reverter "${tpl.label}" para o texto padrão? Sua personalização será removida.`,
        header: 'Reverter ao padrão',
        icon: 'pi-undo',
        color: '#f59e0b',
        accept: async () => {
            if (reverting.value[tpl.key]) return;
            reverting.value[tpl.key] = true;
            try {
                const { error } = await tenantDb().from('notification_templates').update({ deleted_at: new Date().toISOString() }).eq('id', tpl.id);
                if (error) throw error;
                tpl.id = null;
                tpl.is_custom = false;
                tpl.body_text = tpl.default_body;
                tpl.saved_body = tpl.default_body;
                drawerStore.invalidateTemplates();
                toast.add({ severity: 'success', summary: 'Revertido ao padrão', life: 3000 });
            } catch (e) {
                toast.add({ severity: 'error', summary: 'Erro ao reverter', detail: e.message, life: 5000 });
            } finally {
                reverting.value[tpl.key] = false;
            }
        }
    });
}

function isDirty(tpl) {
    return (tpl.body_text || '') !== (tpl.saved_body || '');
}

onMounted(async () => {
    await loadUser();
    await loadTemplates();
});
</script>

<template>
    <div class="flex flex-col gap-4">
        <ConfirmDialog group="headless">
            <template #container="{ message, acceptCallback, rejectCallback }">
                <div class="flex flex-col items-center p-8 bg-surface-0 dark:bg-surface-900 rounded-xl shadow-xl">
                    <div class="rounded-full inline-flex justify-center items-center h-24 w-24 -mt-20" :style="{ background: message.color || 'var(--p-primary-color)', color: '#fff' }">
                        <i :class="`pi ${message.icon || 'pi-question'} !text-4xl`"></i>
                    </div>
                    <span class="font-bold text-2xl block mb-2 mt-6">{{ message.header }}</span>
                    <p class="mb-0 text-center text-[var(--text-color-secondary)]">{{ message.message }}</p>
                    <div class="flex items-center gap-2 mt-6">
                        <Button label="Confirmar" class="rounded-full" :style="{ background: message.color || 'var(--p-primary-color)', borderColor: message.color || 'var(--p-primary-color)' }" @click="acceptCallback" />
                        <Button label="Cancelar" variant="outlined" class="rounded-full" @click="rejectCallback" />
                    </div>
                </div>
            </template>
        </ConfirmDialog>

        <Message severity="info" :closable="false">
            Os textos padrão já funcionam — edite apenas se quiser personalizar. A qualquer momento você pode <strong>reverter ao padrão</strong> definido pelo administrador.
        </Message>

        <template v-if="loading">
            <div v-for="n in 4" :key="n" class="rounded-[6px] border border-[var(--surface-border)] bg-[var(--surface-card)] p-4">
                <div class="flex items-center gap-3 mb-3">
                    <Skeleton width="2.5rem" height="2.5rem" borderRadius="6px" />
                    <div class="flex-1 flex flex-col gap-2">
                        <Skeleton width="10rem" height="1rem" />
                        <Skeleton width="6rem" height="0.75rem" />
                    </div>
                    <Skeleton width="5rem" height="1.4rem" borderRadius="999px" />
                </div>
                <Skeleton width="100%" height="5rem" class="mb-2" />
                <div class="flex gap-1">
                    <Skeleton v-for="i in 3" :key="i" width="6rem" height="1.6rem" borderRadius="999px" />
                </div>
            </div>
        </template>

        <template v-else>
            <div
                v-if="!templates.length"
                class="rounded-[6px] border border-[var(--surface-border)] bg-[var(--surface-card)] p-6 text-center text-[var(--text-color-secondary)]"
            >
                <i class="pi pi-whatsapp text-3xl opacity-30 block mb-2" />
                Nenhum template WhatsApp disponível no momento.
            </div>

            <div
                v-for="tpl in templates"
                :key="tpl.key"
                class="rounded-[6px] border bg-[var(--surface-card)] p-4 flex flex-col gap-3 overflow-hidden"
                :class="tpl.is_custom ? 'border-green-300' : 'border-[var(--surface-border)]'"
            >
                <div class="flex items-center gap-3 flex-wrap">
                    <div
                        class="w-10 h-10 rounded-[6px] flex items-center justify-center shrink-0"
                        :class="tpl.is_custom ? 'bg-green-100 text-green-700' : 'bg-[var(--surface-ground)] text-[var(--text-color-secondary)]'"
                    >
                        <i class="pi pi-whatsapp text-lg" />
                    </div>
                    <div class="flex-1 min-w-0">
                        <div class="font-semibold text-[var(--text-color)]">{{ tpl.label }}</div>
                        <div class="text-xs text-[var(--text-color-secondary)] flex items-center gap-1.5 mt-0.5">
                            <Tag :value="tpl.domain_label" :severity="tpl.type_severity" class="text-[0.6rem]" />
                            <code class="font-mono opacity-70">{{ tpl.key }}</code>
                        </div>
                    </div>
                    <Tag v-if="tpl.is_custom" value="Personalizado" severity="success" class="text-[0.65rem]" />
                    <Tag v-else value="Padrão" severity="secondary" class="text-[0.65rem]" />
                </div>

                <Textarea
                    :ref="(el) => setTextareaRef(tpl.key, el)"
                    v-model="tpl.body_text"
                    rows="4"
                    auto-resize
                    class="w-full text-sm"
                    :maxlength="4096"
                    placeholder="Digite o texto do template..."
                />

                <div class="flex items-center justify-between flex-wrap gap-2">
                    <span class="text-[0.68rem] text-[var(--text-color-secondary)]">{{ (tpl.body_text || '').length }} / 4096 caracteres</span>
                    <span v-if="isDirty(tpl)" class="text-[0.68rem] text-amber-600 font-medium flex items-center gap-1">
                        <i class="pi pi-circle-fill text-[0.4rem]" />
                        Alterações não salvas
                    </span>
                </div>

                <div v-if="tpl.variables.length" class="flex flex-col gap-1.5">
                    <span class="text-xs text-[var(--text-color-secondary)]">Inserir variável:</span>
                    <div class="flex flex-wrap gap-1.5">
                        <Button
                            v-for="v in tpl.variables"
                            :key="v"
                            size="small"
                            severity="secondary"
                            outlined
                            class="font-mono !text-[0.68rem] !py-1 !px-2"
                            @click="insertVariable(tpl.key, v)"
                        >
                            <span v-text="'{{' + v + '}}'"></span>
                        </Button>
                    </div>
                </div>

                <div class="flex items-center gap-2 justify-end flex-wrap">
                    <Button
                        v-if="tpl.is_custom"
                        label="Reverter ao padrão"
                        icon="pi pi-undo"
                        size="small"
                        severity="secondary"
                        outlined
                        :loading="reverting[tpl.key]"
                        :disabled="reverting[tpl.key]"
                        @click="confirmRevert(tpl)"
                    />
                    <Button
                        label="Salvar"
                        icon="pi pi-check"
                        size="small"
                        :loading="saving[tpl.key]"
                        :disabled="saving[tpl.key] || !isDirty(tpl)"
                        @click="saveTemplate(tpl)"
                    />
                </div>
            </div>
        </template>
    </div>
</template>
