<!--
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/layout/configuracoes/ConfiguracoesEmailTemplatesPage.vue
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
-->
<script setup>
import { ref, computed, onMounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { useToast } from 'primevue/usetoast';
import { useConfirm } from 'primevue/useconfirm';
import JoditEmailEditor from '@/components/ui/JoditEmailEditor.vue';
import { supabase } from '@/lib/supabase/client';
import { tenantDb } from '@/lib/supabase/tenantClient';
import { renderEmail, renderTemplate, generateLayoutSection } from '@/lib/email/emailTemplateService';
import { MOCK_DATA, TEMPLATE_DOMAINS } from '@/lib/email/emailTemplateConstants';

const toast = useToast();
const confirm = useConfirm();
const router = useRouter();
const route = useRoute();

// Em /melissa o "Minha Empresa" foi unificado com /melissa/negocio (mesma
// tabela company_profiles). Preserva o layout em que a pagina foi aberta.
const inMelissa = computed(() => String(route.path || '').startsWith('/melissa'));
function goEmpresa() {
    router.push(inMelissa.value ? '/melissa/negocio' : '/configuracoes/empresa');
}

// ── Contexto ──────────────────────────────────────────────────
const tenantId = ref(null);
const profileLogoUrl = ref(null);

async function loadUser() {
    const {
        data: { user }
    } = await supabase.auth.getUser();
    if (!user) return;
    tenantId.value = user.id;
    const { data } = await tenantDb().from('company_profiles').select('logo_url').maybeSingle();
    profileLogoUrl.value = data?.logo_url || null;
}

// ── Layout config global (header/footer do tenant) ────────────
const layoutConfigId = ref(null);
const layoutConfig = ref({ header: defaultSection(), footer: defaultSection() });

function defaultSection() {
    return { enabled: false, content: '', layout: null };
}

async function loadLayoutConfig() {
    if (!tenantId.value) return;
    const { data } = await tenantDb().from('email_layout_config').select('*').maybeSingle();
    if (data) {
        layoutConfigId.value = data.id;
        layoutConfig.value.header = { ...defaultSection(), ...(data.header_config || {}) };
        layoutConfig.value.footer = { ...defaultSection(), ...(data.footer_config || {}) };
    }
}

// ── Templates globais + overrides ─────────────────────────────
const globals = ref([]);
const overrides = ref([]);
const loading = ref(false);
const filterDomain = ref(null);

async function load() {
    if (!tenantId.value) return;
    loading.value = true;
    try {
        const [{ data: gData, error: gErr }, { data: oData, error: oErr }] = await Promise.all([
            supabase.from('email_templates_global').select('*').eq('is_active', true).order('domain').order('key'),
            tenantDb().from('email_templates_tenant').select('*').is('owner_id', null)
        ]);
        if (gErr) throw gErr;
        if (oErr) throw oErr;
        globals.value = gData || [];
        overrides.value = oData || [];
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro ao carregar', detail: e.message, life: 4000 });
    } finally {
        loading.value = false;
    }
}

const overrideMap = computed(() => {
    const map = {};
    for (const o of overrides.value) map[o.template_key] = o;
    return map;
});

const filtered = computed(() => {
    const list = filterDomain.value ? globals.value.filter((t) => t.domain === filterDomain.value) : globals.value;
    return list.map((g) => {
        const ov = overrideMap.value[g.key] || null;
        const mock = _mockForDomain(g.domain);
        return {
            ...g,
            override: ov,
            has_override: !!ov,
            needs_sync: ov ? ov.synced_version !== null && ov.synced_version < g.version : false,
            rendered_subject: renderTemplate(ov?.subject ?? g.subject, mock),
            rendered_body_snippet: _bodySnippet(ov?.body_html ?? g.body_html, mock)
        };
    });
});

function _bodySnippet(html, mock) {
    const rendered = renderTemplate(html || '', mock);
    const text = rendered
        .replace(/<br\s*\/?>/gi, ' ')
        .replace(/<[^>]+>/g, '')
        .replace(/\s+/g, ' ')
        .trim();
    return text.length > 100 ? text.slice(0, 100) + '…' : text;
}

function _mockForDomain(domain) {
    if (domain === TEMPLATE_DOMAINS.SESSION) return { ...MOCK_DATA.session };
    if (domain === TEMPLATE_DOMAINS.INTAKE) return { ...MOCK_DATA.intake };
    return { ...MOCK_DATA.system };
}

const DOMAIN_OPTIONS = [
    { label: 'Todos', value: null },
    { label: 'Sessão', value: TEMPLATE_DOMAINS.SESSION },
    { label: 'Triagem', value: TEMPLATE_DOMAINS.INTAKE },
    { label: 'Sistema', value: TEMPLATE_DOMAINS.SYSTEM }
];
const DOMAIN_LABEL = { session: 'Sessão', intake: 'Triagem', billing: 'Financeiro', system: 'Sistema' };
const DOMAIN_SEVERITY = { session: 'info', intake: 'warning', billing: 'success', system: 'secondary' };

// ── Dialog layout (header/footer global) ──────────────────────
const layoutDlg = ref({ open: false, saving: false });
const layoutForm = ref({ header: defaultSection(), footer: defaultSection() });

function openLayoutDlg() {
    layoutForm.value = {
        header: { ...defaultSection(), ...layoutConfig.value.header },
        footer: { ...defaultSection(), ...layoutConfig.value.footer }
    };
    layoutDlg.value = { open: true, saving: false };
}

const headerLayoutPreview = computed(() => generateLayoutSection(layoutForm.value.header, profileLogoUrl.value, true));
const footerLayoutPreview = computed(() => generateLayoutSection(layoutForm.value.footer, profileLogoUrl.value, false));

async function saveLayout() {
    if (!tenantId.value) return;
    layoutDlg.value.saving = true;
    try {
        const payload = {
            tenant_id: tenantId.value,
            header_config: layoutForm.value.header,
            footer_config: layoutForm.value.footer
        };
        if (layoutConfigId.value) {
            const { error } = await tenantDb().from('email_layout_config').update(payload).eq('id', layoutConfigId.value);
            if (error) throw error;
        } else {
            const { data, error } = await tenantDb().from('email_layout_config').insert(payload).select('id').single();
            if (error) throw error;
            layoutConfigId.value = data.id;
        }
        layoutConfig.value.header = { ...layoutForm.value.header };
        layoutConfig.value.footer = { ...layoutForm.value.footer };
        toast.add({ severity: 'success', summary: 'Layout salvo', life: 3000 });
        layoutDlg.value.open = false;
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro ao salvar', detail: e.message, life: 5000 });
    } finally {
        layoutDlg.value.saving = false;
    }
}

// ── Dialog edição de template ──────────────────────────────────
const dlg = ref({ open: false, saving: false, mode: 'create', globalTemplate: null });
const form = ref({});
const editorRef = ref(null);

function openEdit(row) {
    const ov = row.override;
    form.value = {
        template_key: row.key,
        use_custom_subject: !!ov?.subject,
        use_custom_body: !!ov?.body_html,
        subject: ov?.subject ?? row.subject,
        body_html: ov?.body_html ?? row.body_html,
        body_text: ov?.body_text ?? '',
        synced_version: row.version,
        variables: row.variables || {}
    };
    dlg.value = { open: true, saving: false, mode: ov ? 'edit' : 'create', globalTemplate: row };
}

function closeDlg() {
    dlg.value.open = false;
}

const formVariables = computed(() => {
    const keys = Object.keys(form.value.variables || {});
    if (!keys.includes('clinic_logo_url')) keys.push('clinic_logo_url');
    return keys;
});

function insertVar(varName) {
    const snippet = `{{${varName}}}`;
    if (editorRef.value?.insertHTML) {
        editorRef.value.insertHTML(snippet);
    } else {
        form.value.body_html = (form.value.body_html || '') + snippet;
    }
}

async function save() {
    if (!tenantId.value) return;
    if (form.value.use_custom_subject && !form.value.subject?.trim()) {
        toast.add({ severity: 'warn', summary: 'Subject não pode ser vazio', life: 3000 });
        return;
    }
    dlg.value.saving = true;
    try {
        const payload = {
            tenant_id: tenantId.value,
            owner_id: null,
            template_key: form.value.template_key,
            subject: form.value.use_custom_subject ? form.value.subject : null,
            body_html: form.value.use_custom_body ? form.value.body_html : null,
            body_text: form.value.use_custom_body && form.value.body_text ? form.value.body_text : null,
            enabled: true,
            synced_version: form.value.synced_version
        };
        if (dlg.value.mode === 'create') {
            const { error } = await tenantDb().from('email_templates_tenant').insert(payload);
            if (error) throw error;
            toast.add({ severity: 'success', summary: 'Personalização salva', life: 3000 });
        } else {
            const { error } = await tenantDb().from('email_templates_tenant').update(payload).eq('id', overrideMap.value[form.value.template_key].id);
            if (error) throw error;
            toast.add({ severity: 'success', summary: 'Personalização salva', life: 3000 });
        }
        closeDlg();
        await load();
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro ao salvar', detail: e.message, life: 5000 });
    } finally {
        dlg.value.saving = false;
    }
}

function confirmRevert(row) {
    confirm.require({
        message: `Reverter "${row.key}" para o template global?`,
        header: 'Remover personalização',
        icon: 'pi pi-undo',
        acceptClass: 'p-button-danger',
        accept: async () => {
            try {
                const { error } = await tenantDb().from('email_templates_tenant').delete().eq('id', row.override.id);
                if (error) throw error;
                toast.add({ severity: 'success', summary: 'Revertido para o padrão', life: 3000 });
                await load();
            } catch (e) {
                toast.add({ severity: 'error', summary: 'Erro', detail: e.message, life: 4000 });
            }
        }
    });
}

// ── Dialog preview ─────────────────────────────────────────────
const preview = ref({ open: false, subject: '', body_html: '', key: '', source: '' });

function openPreview(row) {
    const resolved = {
        ...row,
        subject: row.override?.subject ?? row.subject,
        body_html: row.override?.body_html ?? row.body_html,
        body_text: row.override?.body_text ?? row.body_text
    };
    const mock = {
        ..._mockForDomain(row.domain),
        clinic_logo_url: profileLogoUrl.value || null
    };
    const rendered = renderEmail(resolved, mock, {
        headerConfig: layoutConfig.value.header,
        footerConfig: layoutConfig.value.footer,
        logoUrl: profileLogoUrl.value
    });
    preview.value = { open: true, ...rendered, key: row.key, source: row.has_override ? 'personalizado' : 'global' };
}

const layoutActive = computed(() => layoutConfig.value.header.enabled || layoutConfig.value.footer.enabled);

onMounted(async () => {
    await loadUser();
    await Promise.all([load(), loadLayoutConfig()]);
});
</script>

<template>
    <div class="flex flex-col gap-4">
        <!-- Filtro + Layout global -->
        <div class="flex items-center gap-2 flex-wrap">
            <Button v-for="opt in DOMAIN_OPTIONS" :key="String(opt.value)" :label="opt.label" size="small" :severity="filterDomain === opt.value ? 'primary' : 'secondary'" :outlined="filterDomain !== opt.value" @click="filterDomain = opt.value" />
            <div class="ml-auto">
                <Button
                    label="Layout global"
                    icon="pi pi-palette"
                    size="small"
                    :severity="layoutActive ? 'success' : 'secondary'"
                    :outlined="!layoutActive"
                    @click="openLayoutDlg"
                />
            </div>
        </div>

        <!-- ══ SKELETON ══════════════════════════════════════════════ -->
        <template v-if="loading">
            <div class="flex flex-col gap-2">
                <div v-for="n in 5" :key="n" class="border border-[var(--surface-border)] rounded-xl bg-[var(--surface-card)] px-4 py-3 flex gap-3 items-center">
                    <Skeleton width="4.5rem" height="1.4rem" border-radius="999px" />
                    <div class="flex flex-col gap-1.5 flex-1">
                        <Skeleton :width="n % 2 === 0 ? '14rem' : '10rem'" height="11px" />
                        <Skeleton :width="n % 3 === 0 ? '20rem' : '16rem'" height="10px" />
                    </div>
                    <div class="flex gap-1">
                        <Skeleton width="2rem" height="2rem" border-radius="6px" />
                        <Skeleton width="2rem" height="2rem" border-radius="6px" />
                    </div>
                </div>
            </div>
            <AppLoadingPhrases action="Carregando templates de e-mail..." containerClass="py-6" />
        </template>

        <!-- Lista -->
        <div v-else class="flex flex-col gap-2">
            <div v-for="row in filtered" :key="row.id" class="border border-[var(--surface-border)] rounded-xl bg-[var(--surface-card)] px-4 py-3 flex gap-3 items-center">
                <Tag :value="DOMAIN_LABEL[row.domain] ?? row.domain" :severity="DOMAIN_SEVERITY[row.domain] ?? 'secondary'" class="text-[0.7rem] shrink-0 self-start mt-0.5" />

                <div class="flex-1 min-w-0">
                    <div class="flex items-center gap-2 flex-wrap mb-0.5">
                        <span class="font-mono text-xs text-[var(--text-color-secondary)]">{{ row.key }}</span>
                        <Tag v-if="row.has_override" value="Personalizado" severity="success" class="text-[0.65rem]" />
                        <Tag v-if="row.needs_sync" value="Desatualizado" severity="warning" class="text-[0.65rem]" />
                    </div>
                    <div class="text-sm font-medium truncate">{{ row.rendered_subject }}</div>
                    <div class="text-xs text-[var(--text-color-secondary)] truncate mt-0.5">{{ row.rendered_body_snippet }}</div>
                </div>

                <div class="flex items-center gap-1 shrink-0">
                    <Button icon="pi pi-eye" text rounded size="small" severity="secondary" title="Preview" @click="openPreview(row)" />
                    <Button :icon="row.has_override ? 'pi pi-pencil' : 'pi pi-sliders-h'" text rounded size="small" :title="row.has_override ? 'Editar personalização' : 'Personalizar'" @click="openEdit(row)" />
                    <Button v-if="row.has_override" icon="pi pi-undo" text rounded size="small" severity="danger" title="Reverter para padrão" @click="confirmRevert(row)" />
                </div>
            </div>
            <LoadedPhraseBlock />
        </div>

        <!-- ── Dialog Layout Global (Header/Footer) ─────────────── -->
        <Dialog v-model:visible="layoutDlg.open" header="Personalizar Layout do E-mail" modal :style="{ width: '820px', maxWidth: '96vw' }" :draggable="false">
            <div class="flex flex-col gap-4 py-2">
                <!-- Banner: trocar logo -->
                <div class="flex items-center gap-3 px-3 py-2.5 rounded-lg border border-[var(--surface-border)] bg-[var(--surface-ground)]">
                    <i class="pi pi-image text-[var(--text-color-secondary)] text-sm opacity-60" />
                    <span class="text-sm flex-1 text-[var(--text-color-secondary)]"> Para trocar sua logo, acesse <strong>Minha Empresa</strong>. </span>
                    <Button :label="inMelissa ? 'Meu Negócio' : 'Minha Empresa'" icon="pi pi-building" size="small" severity="secondary" outlined class="shrink-0" @click="goEmpresa" />
                </div>

                <!-- ── HEADER ──────────────────────────────────────── -->
                <div class="border border-[var(--surface-border)] rounded-lg overflow-hidden">
                    <div class="flex items-center justify-between px-4 py-3 bg-[var(--surface-ground)]">
                        <div class="flex items-center gap-2">
                            <i class="pi pi-arrow-up text-xs opacity-50" />
                            <span class="text-sm font-semibold">Header</span>
                        </div>
                        <div class="flex items-center gap-2">
                            <ToggleSwitch v-model="layoutForm.header.enabled" inputId="sw-header" />
                            <label for="sw-header" class="text-xs cursor-pointer select-none">Ativo</label>
                        </div>
                    </div>

                    <div v-if="layoutForm.header.enabled" class="px-4 py-4 flex flex-col gap-4">
                        <!-- Editor Jodit — use os botões "▣ Logo Esq./Dir./Centro" na toolbar para inserir layouts prontos -->
                        <JoditEmailEditor
                            v-model="layoutForm.header.content"
                            :min-height="160"
                            :layout-buttons="true"
                            :logo-url="profileLogoUrl"
                        />

                        <!-- Preview -->
                        <div v-if="headerLayoutPreview" class="rounded-lg border border-(--surface-border) bg-(--surface-ground) p-3">
                            <span class="text-[0.65rem] text-(--text-color-secondary) uppercase tracking-widest block mb-2">Preview</span>
                            <div class="rounded border border-(--surface-border) bg-white p-3 text-sm text-gray-800 shadow-sm">
                                <!-- eslint-disable-next-line vue/no-v-html -->
                                <div v-html="headerLayoutPreview" />
                            </div>
                        </div>
                    </div>
                </div>

                <!-- ── FOOTER ──────────────────────────────────────── -->
                <div class="border border-[var(--surface-border)] rounded-lg overflow-hidden">
                    <div class="flex items-center justify-between px-4 py-3 bg-[var(--surface-ground)]">
                        <div class="flex items-center gap-2">
                            <i class="pi pi-arrow-down text-xs opacity-50" />
                            <span class="text-sm font-semibold">Rodapé</span>
                        </div>
                        <div class="flex items-center gap-2">
                            <ToggleSwitch v-model="layoutForm.footer.enabled" inputId="sw-footer" />
                            <label for="sw-footer" class="text-xs cursor-pointer select-none">Ativo</label>
                        </div>
                    </div>

                    <div v-if="layoutForm.footer.enabled" class="px-4 py-4 flex flex-col gap-4">
                        <!-- Editor Jodit — use os botões "▣ Logo Esq./Dir./Centro" na toolbar para inserir layouts prontos -->
                        <JoditEmailEditor
                            v-model="layoutForm.footer.content"
                            :min-height="160"
                            :layout-buttons="true"
                            :logo-url="profileLogoUrl"
                        />

                        <!-- Preview -->
                        <div v-if="footerLayoutPreview" class="rounded-lg border border-(--surface-border) bg-(--surface-ground) p-3">
                            <span class="text-[0.65rem] text-(--text-color-secondary) uppercase tracking-widest block mb-2">Preview</span>
                            <div class="rounded border border-(--surface-border) bg-white p-3 text-sm text-gray-800 shadow-sm">
                                <!-- eslint-disable-next-line vue/no-v-html -->
                                <div v-html="footerLayoutPreview" />
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <template #footer>
                <Button label="Cancelar" text @click="layoutDlg.open = false" :disabled="layoutDlg.saving" />
                <Button label="Salvar layout" icon="pi pi-check" :loading="layoutDlg.saving" @click="saveLayout" />
            </template>
        </Dialog>

        <!-- ── Dialog Edição de Template ────────────────────────── -->
        <Dialog v-model:visible="dlg.open" :header="dlg.mode === 'create' ? `Personalizar — ${form.template_key}` : `Editar — ${form.template_key}`" modal :style="{ width: '840px', maxWidth: '96vw' }" :draggable="false">
            <div class="flex flex-col gap-4 py-2">
                <!-- Subject -->
                <div class="border border-[var(--surface-border)] rounded-lg overflow-hidden">
                    <div class="flex items-center justify-between px-4 py-3 bg-[var(--surface-ground)]">
                        <span class="text-sm font-semibold">Subject</span>
                        <div class="flex items-center gap-2">
                            <ToggleSwitch v-model="form.use_custom_subject" inputId="sw-custom-subject" />
                            <label for="sw-custom-subject" class="text-xs cursor-pointer select-none">Personalizar</label>
                        </div>
                    </div>
                    <div class="px-4 py-3">
                        <InputText v-if="form.use_custom_subject" v-model="form.subject" class="w-full" />
                        <p v-else class="text-xs text-[var(--text-color-secondary)] m-0 italic">Usando padrão: "{{ dlg.globalTemplate?.subject }}"</p>
                    </div>
                </div>

                <!-- Corpo -->
                <div class="border border-[var(--surface-border)] rounded-lg overflow-hidden">
                    <div class="flex items-center justify-between px-4 py-3 bg-[var(--surface-ground)]">
                        <span class="text-sm font-semibold">Corpo do e-mail</span>
                        <div class="flex items-center gap-2">
                            <ToggleSwitch v-model="form.use_custom_body" inputId="sw-custom-body" />
                            <label for="sw-custom-body" class="text-xs cursor-pointer select-none">Personalizar</label>
                        </div>
                    </div>
                    <div class="px-4 py-3 flex flex-col gap-3">
                        <template v-if="form.use_custom_body">
                            <JoditEmailEditor ref="editorRef" v-model="form.body_html" :min-height="220" />
                            <div class="flex flex-col gap-1.5">
                                <span class="text-xs text-[var(--text-color-secondary)]">Inserir variável no cursor:</span>
                                <div class="flex flex-wrap gap-1.5">
                                    <Button v-for="v in formVariables" :key="v" :label="`{{${v}}}`" size="small" severity="secondary" outlined class="font-mono !text-[0.68rem] !py-1 !px-2" @click="insertVar(v)" />
                                </div>
                            </div>
                            <div class="flex flex-col gap-1">
                                <label class="text-xs font-semibold">Versão texto <span class="font-normal opacity-60">(gerado do HTML se vazio)</span></label>
                                <Textarea v-model="form.body_text" rows="2" class="w-full text-xs" auto-resize />
                            </div>
                        </template>
                        <p v-else class="text-xs text-[var(--text-color-secondary)] m-0 italic">Usando o corpo padrão do sistema.</p>
                    </div>
                </div>

            </div>

            <template #footer>
                <Button label="Cancelar" text @click="closeDlg" :disabled="dlg.saving" />
                <Button :label="dlg.mode === 'create' ? 'Salvar personalização' : 'Salvar'" icon="pi pi-check" :loading="dlg.saving" @click="save" />
            </template>
        </Dialog>

        <!-- ── Dialog Preview ──────────────────────────────────── -->
        <Dialog v-model:visible="preview.open" :header="`Preview — ${preview.key}`" modal :style="{ width: '680px', maxWidth: '96vw' }" :draggable="false">
            <div class="flex flex-col gap-3">
                <div class="flex justify-center">
                    <Tag :value="preview.source === 'personalizado' ? 'Usando sua personalização' : 'Usando template global'" :severity="preview.source === 'personalizado' ? 'success' : 'secondary'" />
                </div>
                <div class="border border-[var(--surface-border)] rounded-lg p-3 bg-[var(--surface-ground)]">
                    <span class="text-xs font-semibold text-[var(--text-color-secondary)] uppercase tracking-widest">Subject</span>
                    <p class="mt-1 mb-0 font-medium">{{ preview.subject }}</p>
                </div>
                <div class="border border-[var(--surface-border)] rounded-lg p-5 bg-white text-gray-800 text-sm leading-relaxed">
                    <!-- eslint-disable-next-line vue/no-v-html -->
                    <div v-html="preview.body_html" />
                </div>
                <p v-if="!profileLogoUrl" class="text-xs text-[var(--text-color-secondary)] m-0 text-center">Adicione um avatar no seu perfil para exibir o logo no header/rodapé.</p>
            </div>
            <template #footer>
                <Button label="Fechar" @click="preview.open = false" />
            </template>
        </Dialog>

        <ConfirmDialog />
    </div>
</template>

<style scoped>
</style>
