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

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

// "Trocar canal" volta pro chooser. Mantem o usuario no layout em que esta:
// /melissa/cfg-wa se aberto via Melissa, /configuracoes/whatsapp caso contrario.
const inMelissa = computed(() => String(route.path || '').startsWith('/melissa'));
const chooserPath = computed(() => (inMelissa.value ? '/melissa/cfg-wa' : '/configuracoes/whatsapp'));

// Detecta area (admin clinica vs therapist) pra direcionar corretamente
function goConversas() {
    const role = tenantStore.activeRole || tenantStore.role || '';
    const isTherapistArea = role === 'therapist';
    router.push(isTherapistArea ? '/therapist/conversas' : '/admin/conversas');
}

// ── Contexto ──────────────────────────────────────────────────
const userId = ref(null);
const tenantId = ref(null); // tenant_id real (da tabela tenants)
const activeTab = ref(0);

async function loadUser() {
    const {
        data: { user }
    } = await supabase.auth.getUser();
    if (!user) return;
    userId.value = user.id;
    // Usar o tenantId do store (tabela tenants), fallback para user.id
    tenantId.value = tenantStore.activeTenantId || user.id;
}

// ══════════════════════════════════════════════════════════════
// ABA 1 — Conexão WhatsApp
// ══════════════════════════════════════════════════════════════

const credentials = ref({ api_url: '', api_key: '', instance_name: '' });
const hasCredentials = ref(false);
const channelRecord = ref(null); // row de notification_channels pra sincronizar connection_status
const connectionStatus = ref(null); // 'open' | 'close' | 'connecting' | null
const connectionLoading = ref(false);

// QR Code
const qrDialog = ref(false);
const qrCodeBase64 = ref(null);
const qrLoading = ref(false);
const qrCountdown = ref(0);
let qrTimer = null;
let isMounted = true;

const connectionTag = computed(() => {
    if (connectionLoading.value) return { label: 'Verificando...', severity: 'secondary' };
    if (!hasCredentials.value) return { label: 'Não configurado', severity: 'secondary' };
    switch (connectionStatus.value) {
        case 'open':
            return { label: 'Conectado', severity: 'success' };
        case 'connecting':
            return { label: 'Conectando...', severity: 'warn' };
        default:
            return { label: 'Desconectado', severity: 'danger' };
    }
});

const softDeletedRecord = ref(null);
const reactivating = ref(false);

// Carregar credenciais do banco — busca por tenant_id (consistente com SaaS)
// com fallback para owner_id (caso tenantId == userId)
async function loadCredentials() {
    if (!tenantId.value) return;
    softDeletedRecord.value = null;

    // 1) Tentar canal ativo por tenant_id (evolution_api)
    let { data, error } = await supabase
        .from('notification_channels')
        .select('*')
        .eq('tenant_id', tenantId.value)
        .eq('channel', 'whatsapp')
        .eq('provider', 'evolution_api')
        .is('deleted_at', null)
        .maybeSingle();

    // Fallback 1: buscar por owner_id (cenário legado ou tenant solo)
    if (!data && userId.value && userId.value !== tenantId.value) {
        const fallback = await supabase
            .from('notification_channels')
            .select('*')
            .eq('owner_id', userId.value)
            .eq('channel', 'whatsapp')
            .eq('provider', 'evolution_api')
            .is('deleted_at', null)
            .maybeSingle();
        data = fallback.data;
        error = fallback.error;
    }

    if (error) {
        toast.add({ severity: 'error', summary: 'Erro ao carregar credenciais', detail: error.message, life: 4000 });
        return;
    }

    if (data?.credentials) {
        credentials.value = {
            api_url: data.credentials.api_url || '',
            api_key: data.credentials.api_key || '',
            instance_name: data.credentials.instance_name || ''
        };
        hasCredentials.value = true;
        channelRecord.value = data;
        return;
    }

    // 2) Não tem ativo — verifica soft-deleted pra oferecer reativar
    const { data: deleted } = await supabase
        .from('notification_channels')
        .select('*')
        .eq('tenant_id', tenantId.value)
        .eq('channel', 'whatsapp')
        .eq('provider', 'evolution_api')
        .not('deleted_at', 'is', null)
        .order('created_at', { ascending: false })
        .limit(1)
        .maybeSingle();
    if (deleted) softDeletedRecord.value = deleted;
}

async function reactivateChannel() {
    if (!softDeletedRecord.value?.id) return;
    reactivating.value = true;
    try {
        const { data, error } = await supabase.functions.invoke('reactivate-notification-channel', {
            body: { channel_id: softDeletedRecord.value.id }
        });
        if (error || !data?.ok) throw new Error(error?.message || data?.error || 'reactivation_failed');

        toast.add({
            severity: 'success',
            summary: 'Canal reativado',
            detail: data.deactivated_others > 0
                ? `Conexão WhatsApp restaurada. ${data.deactivated_others} canal(is) alternativo(s) foi/foram desativado(s).`
                : 'Conexão WhatsApp restaurada. Agora escaneie o QR Code pra conectar o celular.',
            life: 4500
        });

        await loadCredentials();
        await loadHeartbeatConfig();
        await loadIncidents();
        if (hasCredentials.value) await checkConnectionStatus();
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Não foi possível reativar', detail: e.message || 'Tente novamente ou contate o suporte.', life: 5000 });
    } finally {
        reactivating.value = false;
    }
}

// Verificar status da conexão via Evolution API
async function checkConnectionStatus() {
    if (!hasCredentials.value) return;
    connectionLoading.value = true;
    try {
        const res = await fetch(`${credentials.value.api_url}/instance/fetchInstances`, {
            headers: { apikey: credentials.value.api_key }
        });
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        const instances = await res.json();
        // Evolution v1 retorna [{ instance: { instanceName, status } }], v2 retorna [{ instanceName, connectionStatus/state }]
        const arr = Array.isArray(instances) ? instances : [];
        const inst = arr.find((i) => {
            const name = i?.instance?.instanceName ?? i?.instanceName ?? i?.name;
            return name === credentials.value.instance_name;
        });
        const rawState = inst?.instance?.status ?? inst?.instance?.state ?? inst?.connectionStatus ?? inst?.state ?? inst?.status;
        connectionStatus.value = rawState || 'close';

        // Persiste no DB pra SaaS admin ver status atualizado na listagem
        if (channelRecord.value?.id) {
            const dbStatus = rawState === 'open' ? 'connected' : rawState === 'connecting' ? 'connecting' : 'disconnected';
            if (channelRecord.value.connection_status !== dbStatus) {
                await supabase
                    .from('notification_channels')
                    .update({ connection_status: dbStatus, last_health_check: new Date().toISOString() })
                    .eq('id', channelRecord.value.id);
                channelRecord.value.connection_status = dbStatus;
            }
        }
    } catch (e) {
        connectionStatus.value = 'close';
        toast.add({
            severity: 'warn',
            summary: 'Não foi possível conectar à Evolution API',
            detail: 'Verifique a URL e a chave de API.',
            life: 5000
        });
    } finally {
        connectionLoading.value = false;
    }
}

// ──────────────────────────────────────────────────────────────
// Monitoramento de conexão (Heartbeat — Grupo 6.1)
// ──────────────────────────────────────────────────────────────
const heartbeatConfig = ref({
    threshold_minutes: 5,
    alerts_enabled: true,
    reconnect_enabled: true
});
const heartbeatConfigSaving = ref(false);
const incidents = ref([]);
const incidentsLoading = ref(false);

async function loadHeartbeatConfig() {
    if (!channelRecord.value) return;
    const meta = channelRecord.value.metadata || {};
    heartbeatConfig.value = {
        threshold_minutes: Number(meta.heartbeat_threshold_minutes) || 5,
        alerts_enabled: meta.heartbeat_alerts_enabled !== false,
        reconnect_enabled: meta.heartbeat_reconnect_enabled !== false
    };
}

async function saveHeartbeatConfig() {
    if (!channelRecord.value?.id) return;
    heartbeatConfigSaving.value = true;
    try {
        const threshold = Math.max(1, Math.min(60, Math.round(Number(heartbeatConfig.value.threshold_minutes) || 5)));
        const newMeta = {
            ...(channelRecord.value.metadata || {}),
            heartbeat_threshold_minutes: threshold,
            heartbeat_alerts_enabled: !!heartbeatConfig.value.alerts_enabled,
            heartbeat_reconnect_enabled: !!heartbeatConfig.value.reconnect_enabled
        };
        const { error } = await supabase
            .from('notification_channels')
            .update({ metadata: newMeta })
            .eq('id', channelRecord.value.id);
        if (error) throw error;
        channelRecord.value.metadata = newMeta;
        heartbeatConfig.value.threshold_minutes = threshold;
        toast.add({ severity: 'success', summary: 'Configuração salva', life: 2000 });
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro', detail: e.message, life: 4000 });
    } finally {
        heartbeatConfigSaving.value = false;
    }
}

async function loadIncidents() {
    if (!tenantId.value || !channelRecord.value?.id) return;
    incidentsLoading.value = true;
    try {
        const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 3600 * 1000).toISOString();
        const { data, error } = await supabase
            .from('whatsapp_connection_incidents')
            .select('id, kind, last_state, started_at, resolved_at, duration_seconds, notified_at')
            .eq('channel_id', channelRecord.value.id)
            .gte('started_at', sevenDaysAgo)
            .order('started_at', { ascending: false })
            .limit(30);
        if (error) throw error;
        incidents.value = data || [];
    } catch (e) {
        toast.add({ severity: 'warn', summary: 'Histórico indisponível', detail: e.message, life: 3000 });
    } finally {
        incidentsLoading.value = false;
    }
}

function formatDuration(seconds) {
    if (!seconds && seconds !== 0) return '—';
    const s = Number(seconds);
    if (s < 60) return `${s}s`;
    if (s < 3600) return `${Math.floor(s / 60)}min ${s % 60}s`;
    const h = Math.floor(s / 3600);
    const m = Math.floor((s % 3600) / 60);
    return `${h}h ${m}min`;
}

function incidentKindLabel(kind) {
    return {
        disconnected: 'Desconectado',
        error: 'Erro',
        qr_pending: 'Aguardando QR',
        connecting: 'Conectando',
        unknown: 'Desconhecido'
    }[kind] || kind;
}

function incidentKindSeverity(kind) {
    return {
        disconnected: 'danger',
        error: 'danger',
        qr_pending: 'warn',
        connecting: 'info',
        unknown: 'secondary'
    }[kind] || 'secondary';
}

// Buscar QR Code para conectar
async function fetchQrCode() {
    if (!isMounted) return;
    qrLoading.value = true;
    qrCodeBase64.value = null;
    clearQrTimer();
    try {
        const res = await fetch(`${credentials.value.api_url}/instance/connect/${credentials.value.instance_name}`, { headers: { apikey: credentials.value.api_key } });
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        const data = await res.json();
        // Evolution v1: data.qrcode.base64 · v2: data.base64 · variantes: data.code/qr/qrCode
        const base64 =
            data?.base64 ||
            data?.qrcode?.base64 ||
            data?.qrCode?.base64 ||
            data?.qr?.base64 ||
            data?.qr ||
            data?.code ||
            null;
        if (!base64) {
            const openState =
                data?.instance?.status === 'open' ||
                data?.instance?.state === 'open' ||
                data?.state === 'open' ||
                data?.status === 'open';
            if (openState) {
                connectionStatus.value = 'open';
                toast.add({ severity: 'success', summary: 'WhatsApp já está conectado!', life: 3000 });
                qrDialog.value = false;
                return;
            }
            console.error('[QR] Resposta inesperada da Evolution:', data);
            throw new Error('QR Code não retornado pela API. Veja o console (F12) pra debug.');
        }
        qrCodeBase64.value = base64.startsWith('data:') ? base64 : `data:image/png;base64,${base64}`;
        startQrCountdown();
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro ao gerar QR Code', detail: e.message, life: 5000 });
    } finally {
        qrLoading.value = false;
    }
}

function startQrCountdown() {
    qrCountdown.value = 30;
    qrTimer = setInterval(() => {
        qrCountdown.value--;
        if (qrCountdown.value <= 0) {
            clearQrTimer();
            fetchQrCode();
        }
    }, 1000);
}

function clearQrTimer() {
    if (qrTimer) {
        clearInterval(qrTimer);
        qrTimer = null;
    }
    qrCountdown.value = 0;
}

function openQrDialog() {
    qrDialog.value = true;
    fetchQrCode();
}

// ══════════════════════════════════════════════════════════════
// Inbox (Fase 5a) — configurar webhook MESSAGES_UPSERT na Evolution
// ══════════════════════════════════════════════════════════════
const inboxProvisioning = ref(false);
const inboxWebhookUrl = ref('');

// Resolve URL pública do Supabase pra Evolution conseguir alcançar a edge function.
// Em dev local, localhost de dentro do container Evolution não funciona — precisa host.docker.internal.
function resolveSupabasePublicUrl() {
    const envUrl = import.meta.env.VITE_SUPABASE_URL || '';
    try {
        const u = new URL(envUrl);
        if (u.hostname === 'localhost' || u.hostname === '127.0.0.1') {
            u.hostname = 'host.docker.internal';
            return u.toString().replace(/\/+$/, '');
        }
    } catch {}
    return envUrl.replace(/\/+$/, '');
}

async function provisionInbox() {
    if (!tenantId.value) {
        toast.add({ severity: 'warn', summary: 'Tenant inválido', life: 3000 });
        return;
    }
    if (!credentials.value?.api_url || !credentials.value?.api_key || !credentials.value?.instance_name) {
        toast.add({ severity: 'warn', summary: 'Salve as credenciais antes', detail: 'URL, API key e nome da instância são obrigatórios.', life: 4000 });
        return;
    }
    inboxProvisioning.value = true;
    try {
        const publicUrl = resolveSupabasePublicUrl();
        const { data, error } = await supabase.functions.invoke('evolution-webhook-provision', {
            body: {
                tenant_id: tenantId.value,
                api_url: credentials.value.api_url,
                api_key: credentials.value.api_key,
                instance_name: credentials.value.instance_name,
                public_url: publicUrl
            }
        });
        if (error) throw error;
        if (!data?.ok) throw new Error(data?.error || 'Falha no provisionamento');
        inboxWebhookUrl.value = data.webhook_url;
        toast.add({ severity: 'success', summary: 'Inbox conectada!', detail: 'Mensagens recebidas agora vão aparecer em /admin/conversas.', life: 5000 });
    } catch (err) {
        toast.add({ severity: 'error', summary: 'Falha ao configurar inbox', detail: err?.message || String(err), life: 6000 });
    } finally {
        inboxProvisioning.value = false;
    }
}

function closeQrDialog() {
    qrDialog.value = false;
    clearQrTimer();
    qrCodeBase64.value = null;
    // Verificar se conectou depois de fechar o dialog
    checkConnectionStatus();
}

// ══════════════════════════════════════════════════════════════
// ABA 2 — Templates de mensagem
// ══════════════════════════════════════════════════════════════

const templates = ref([]);
const templatesLoading = ref(false);
const templateSaving = ref({});

// Labels para exibição por event_type
const EVENT_TYPE_LABELS = {
    lembrete_sessao: 'Lembrete',
    confirmacao_sessao: 'Confirmação',
    cancelamento_sessao: 'Cancelamento',
    reagendamento: 'Reagendamento',
    cobranca_pendente: 'Financeiro',
    boas_vindas_paciente: 'Boas-vindas',
    intake_recebido: 'Triagem',
    intake_aprovado: 'Triagem'
};
const EVENT_SEVERITY = {
    lembrete_sessao: 'info',
    confirmacao_sessao: 'success',
    cancelamento_sessao: 'danger',
    reagendamento: 'warn',
    cobranca_pendente: 'warning',
    boas_vindas_paciente: 'success',
    intake_recebido: 'info',
    intake_aprovado: 'success'
};

// Label amigável a partir da key (ex: 'session.lembrete.whatsapp' → 'Lembrete de sessão')
function keyToLabel(key) {
    const parts = key.replace('.whatsapp', '').split('.');
    const map = {
        'session.lembrete': 'Lembrete de sessão (24h antes)',
        'session.lembrete_2h': 'Lembrete de sessão (2h antes)',
        'session.confirmacao': 'Confirmação de agendamento',
        'session.cancelamento': 'Sessão cancelada',
        'session.reagendamento': 'Sessão reagendada',
        'cobranca.pendente': 'Cobrança pendente',
        'sistema.boas_vindas': 'Boas-vindas ao paciente'
    };
    return map[parts.slice(0, 2).join('.')] || key;
}

// Referências dos textareas para inserção no cursor
const textareaRefs = ref({});

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

async function loadTemplates() {
    if (!tenantId.value) return;
    templatesLoading.value = true;
    try {
        // 1. Busca templates globais do SaaS (tenant_id IS NULL)
        const { data: globals, error: gErr } = await supabase
            .from('notification_templates')
            .select('*')
            .is('tenant_id', null)
            .eq('channel', 'whatsapp')
            .eq('is_default', true)
            .eq('is_active', true)
            .is('deleted_at', null)
            .order('domain')
            .order('event_type');
        if (gErr) throw gErr;

        // 2. Busca customizações do tenant
        const { data: customs, error: cErr } = await supabase.from('notification_templates').select('*').eq('tenant_id', tenantId.value).eq('channel', 'whatsapp').is('deleted_at', null);
        if (cErr) throw cErr;

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

        // 3. Mescla: para cada global, verifica se o tenant tem customização
        templates.value = (globals || []).map((g) => {
            const custom = customMap[g.key];
            return {
                key: g.key,
                domain: g.domain,
                event_type: g.event_type,
                label: keyToLabel(g.key),
                type: EVENT_TYPE_LABELS[g.event_type] || g.event_type,
                type_severity: EVENT_SEVERITY[g.event_type] || 'secondary',
                variables: g.variables || [],
                default_body: g.body_text,
                id: custom?.id || null,
                body_text: custom?.body_text || g.body_text,
                is_custom: !!custom
            };
        });
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro ao carregar templates', detail: e.message, life: 4000 });
    } finally {
        templatesLoading.value = false;
    }
}

// Inserir variável no textarea na posição do cursor
function insertVariable(templateKey, variable) {
    const snippet = `{{${variable}}}`;
    const tpl = templates.value.find((t) => t.key === templateKey);
    if (!tpl) return;

    const textarea = textareaRefs.value[templateKey]?.$el?.querySelector('textarea');
    if (textarea) {
        const start = textarea.selectionStart;
        const end = textarea.selectionEnd;
        const text = tpl.body_text;
        tpl.body_text = text.substring(0, start) + snippet + text.substring(end);
        nextTick(() => {
            textarea.focus();
            textarea.setSelectionRange(start + snippet.length, start + snippet.length);
        });
    } else {
        // Fallback: adicionar ao final
        tpl.body_text = (tpl.body_text || '') + snippet;
    }
}

// Salvar template individual
async function saveTemplate(tpl) {
    if (!tenantId.value || templateSaving.value[tpl.key]) return;
    templateSaving.value[tpl.key] = true;
    try {
        if (tpl.id) {
            // Atualizar existente
            const { error } = await supabase.from('notification_templates').update({ body_text: tpl.body_text }).eq('id', tpl.id);
            if (error) throw error;
        } else {
            // Verificar se já existe um registro ativo para esta key
            const { data: existing } = await supabase.from('notification_templates').select('id').eq('tenant_id', tenantId.value).eq('key', tpl.key).is('deleted_at', null).maybeSingle();

            if (existing?.id) {
                // Já existe (criado por outra sessão) — atualizar
                const { error } = await supabase.from('notification_templates').update({ body_text: tpl.body_text, is_active: true }).eq('id', existing.id);
                if (error) throw error;
                tpl.id = existing.id;
            } else {
                // Inserir novo
                const { data, error } = await supabase
                    .from('notification_templates')
                    .insert({
                        owner_id: userId.value,
                        tenant_id: tenantId.value,
                        channel: 'whatsapp',
                        key: tpl.key,
                        domain: tpl.domain,
                        event_type: tpl.event_type,
                        body_text: tpl.body_text,
                        variables: tpl.variables,
                        is_active: true,
                        is_default: false
                    })
                    .select('id')
                    .single();
                if (error) throw error;
                tpl.id = data.id;
            }
            tpl.is_custom = true;
        }
        toast.add({ severity: 'success', summary: 'Template salvo', life: 3000 });
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro ao salvar template', detail: e.message, life: 5000 });
    } finally {
        templateSaving.value[tpl.key] = false;
    }
}

// Verificar se template difere do padrão global
function isTemplateModified(tpl) {
    return tpl.default_body ? tpl.body_text !== tpl.default_body : false;
}

// Restaurar template para o padrão global
function confirmRestoreTemplate(tpl) {
    if (!tpl.default_body) return;
    confirm.require({
        group: 'headless',
        message: `Restaurar "${tpl.label}" para o texto original definido pelo administrador?`,
        header: 'Restaurar template',
        icon: 'pi-undo',
        accept: async () => {
            tpl.body_text = tpl.default_body;
            if (tpl.id) {
                await saveTemplate(tpl);
            }
        }
    });
}

// ══════════════════════════════════════════════════════════════
// ABA 2 — Emojis rápidos para o guia de formatação
// ══════════════════════════════════════════════════════════════

const QUICK_EMOJIS = [
    { char: '📅', label: 'Calendário' },
    { char: '⏰', label: 'Relógio / Lembrete' },
    { char: '✅', label: 'Confirmado' },
    { char: '❌', label: 'Cancelado' },
    { char: '🔔', label: 'Notificação' },
    { char: '💬', label: 'Mensagem' },
    { char: '💙', label: 'Cuidado / Saúde' },
    { char: '🌿', label: 'Bem-estar' },
    { char: '🤝', label: 'Parceria / Encontro' },
    { char: '📋', label: 'Formulário / Triagem' },
    { char: '💰', label: 'Financeiro' },
    { char: '🔗', label: 'Link' },
    { char: '📍', label: 'Local' },
    { char: '📞', label: 'Telefone' },
    { char: '🏥', label: 'Clínica' },
    { char: '🧠', label: 'Psicologia' },
    { char: '👤', label: 'Paciente' },
    { char: '🌟', label: 'Destaque' },
    { char: '⚠️', label: 'Atenção' },
    { char: '➡️', label: 'Seta / Próximo passo' },
    { char: '🗓️', label: 'Agenda' },
    { char: '🕐', label: 'Hora' },
    { char: '📩', label: 'Recebido' },
    { char: '🔄', label: 'Reagendamento' }
];

function copyEmoji(char) {
    navigator.clipboard?.writeText(char).catch(() => {});
    toast.add({ severity: 'info', summary: `${char} copiado!`, life: 1500 });
}

// ══════════════════════════════════════════════════════════════
// ABA 3 — Logs de envio
// ══════════════════════════════════════════════════════════════

const logs = ref([]);
const logsLoading = ref(false);
const logsFilter = ref('todos');
const logsPage = ref(1);
const logsPerPage = 20;
const logsTotal = ref(0);

const FILTER_OPTIONS = [
    { label: 'Todos', value: 'todos' },
    { label: 'Enviado', value: 'sent' },
    { label: 'Falhou', value: 'failed' }
];

// Mapear keys para nomes amigáveis (dinâmico a partir dos templates carregados)
function friendlyTemplateKey(key) {
    const tpl = templates.value.find((t) => t.key === key || t.event_type === key);
    return tpl?.label || key || '—';
}

function statusTag(status) {
    switch (status) {
        case 'sent':
            return { label: 'Enviado', severity: 'success' };
        case 'failed':
            return { label: 'Falhou', severity: 'danger' };
        case 'pending':
            return { label: 'Pendente', severity: 'warn' };
        default:
            return { label: status || '—', severity: 'secondary' };
    }
}

function formatDate(dt) {
    if (!dt) return '—';
    const d = new Date(dt);
    return d.toLocaleDateString('pt-BR', { day: '2-digit', month: '2-digit', year: 'numeric' }) + ' ' + d.toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' });
}

async function loadLogs() {
    if (!tenantId.value) return;
    logsLoading.value = true;
    try {
        let query = supabase.from('notification_logs').select('*', { count: 'exact' }).eq('tenant_id', tenantId.value).eq('channel', 'whatsapp').order('created_at', { ascending: false });

        if (logsFilter.value !== 'todos') {
            query = query.eq('status', logsFilter.value);
        }

        const from = (logsPage.value - 1) * logsPerPage;
        const to = from + logsPerPage - 1;
        query = query.range(from, to);

        const { data, error, count } = await query;
        if (error) throw error;
        logs.value = data || [];
        logsTotal.value = count || 0;
    } catch (e) {
        toast.add({ severity: 'error', summary: 'Erro ao carregar logs', detail: e.message, life: 4000 });
    } finally {
        logsLoading.value = false;
    }
}

function onFilterChange(val) {
    logsFilter.value = val;
    logsPage.value = 1;
    loadLogs();
}

function onPageChange(event) {
    logsPage.value = event.page + 1;
    loadLogs();
}

// ══════════════════════════════════════════════════════════════
// Inicialização
// ══════════════════════════════════════════════════════════════

onMounted(async () => {
    await loadUser();
    await Promise.all([loadCredentials(), loadTemplates(), loadLogs()]);
    if (hasCredentials.value) {
        await checkConnectionStatus();
        await loadHeartbeatConfig();
        await loadIncidents();
    }
});

onBeforeUnmount(() => {
    isMounted = false;
    clearQrTimer();
});
</script>

<template>
    <Teleport to="#cfg-page-actions" defer>
        <router-link :to="chooserPath">
            <Button label="Trocar canal" icon="pi pi-arrow-left" severity="secondary" outlined size="small" class="rounded-full" />
        </router-link>
    </Teleport>

    <div class="flex flex-col gap-4">
        <!-- Abas -->
        <Tabs :value="activeTab" @update:value="activeTab = $event">
            <TabList>
                <Tab :value="0"><i class="pi pi-link mr-2" />Conexão</Tab>
                <Tab :value="1"><i class="pi pi-file-edit mr-2" />Templates</Tab>
                <Tab :value="2"><i class="pi pi-list mr-2" />Logs de envio</Tab>
            </TabList>

            <TabPanels>
                <!-- ══ ABA 1 — Conexão ════════════════════════════════════ -->
                <TabPanel :value="0">
                    <div class="flex flex-col gap-4 pt-3">
                        <!-- Canal soft-deleted — oferecer reativação -->
                        <div v-if="!hasCredentials && softDeletedRecord" class="border border-amber-500/40 bg-amber-500/5 rounded-lg p-6 flex flex-col items-center text-center gap-3">
                            <div class="grid place-items-center w-14 h-14 rounded-full bg-amber-100 text-amber-600">
                                <i class="pi pi-history text-2xl" />
                            </div>
                            <div class="font-semibold text-sm text-amber-800 dark:text-amber-300">WhatsApp Pessoal foi usado anteriormente</div>
                            <p class="text-sm text-[var(--text-color-secondary)] m-0 max-w-md">
                                As credenciais continuam salvas — basta reativar e escanear o QR Code novamente. Se você tem outro canal WhatsApp ativo (ex: WhatsApp Oficial), ele será desativado.
                            </p>
                            <Button label="Reativar WhatsApp Pessoal" icon="pi pi-refresh" severity="warn" :loading="reactivating" @click="reactivateChannel" />
                        </div>

                        <!-- Sem credenciais nem histórico — WhatsApp nunca configurado -->
                        <div v-else-if="!hasCredentials" class="border border-[var(--surface-border)] rounded-lg p-6 bg-[var(--surface-card)] text-center">
                            <div class="grid place-items-center w-14 h-14 rounded-full bg-gray-100 text-gray-400 mx-auto mb-3">
                                <i class="pi pi-comments text-2xl" />
                            </div>
                            <div class="font-semibold text-sm mb-1">WhatsApp ainda não configurado</div>
                            <p class="text-sm text-[var(--text-color-secondary)] m-0 max-w-md mx-auto">
                                A integração com o WhatsApp precisa ser ativada pela equipe de suporte. Entre em contato para que possamos configurar o envio automático de mensagens para você.
                            </p>
                        </div>

                        <!-- Com credenciais: status + QR Code -->
                        <template v-else>
                            <!-- Status da conexão -->
                            <div class="border border-[var(--surface-border)] rounded-lg p-4 bg-[var(--surface-card)]">
                                <div class="flex items-center justify-between gap-3 flex-wrap">
                                    <div class="flex items-center gap-3">
                                        <div class="grid place-items-center w-10 h-10 rounded-full" :class="connectionStatus === 'open' ? 'bg-green-100 text-green-600' : 'bg-gray-100 text-gray-500'">
                                            <i class="pi pi-comments text-lg" />
                                        </div>
                                        <div>
                                            <div class="font-semibold text-sm">Status da conexão</div>
                                            <Tag :value="connectionTag.label" :severity="connectionTag.severity" class="text-xs mt-1" />
                                        </div>
                                    </div>
                                    <div class="flex gap-2">
                                        <Button :label="connectionStatus === 'open' ? 'Reconectar' : 'Conectar WhatsApp'" icon="pi pi-qrcode" size="small" @click="openQrDialog" />
                                        <Button icon="pi pi-refresh" size="small" severity="secondary" outlined :loading="connectionLoading" v-tooltip.bottom="'Verificar status'" @click="checkConnectionStatus" />
                                    </div>
                                </div>
                            </div>

                            <!-- Instruções simples para o terapeuta -->
                            <div v-if="connectionStatus !== 'open'" class="flex items-start gap-3 px-4 py-3 rounded-lg border border-[var(--surface-border)] bg-[var(--surface-ground)]">
                                <i class="pi pi-info-circle text-[var(--primary-color)] mt-0.5" />
                                <div class="text-sm text-[var(--text-color-secondary)]">
                                    <strong class="text-[var(--text-color)]">Como conectar:</strong>
                                    clique em <strong>"Conectar WhatsApp"</strong>, abra o WhatsApp no seu celular, vá em <strong>Configurações > Aparelhos conectados > Conectar aparelho</strong>
                                    e escaneie o QR Code que aparecerá na tela.
                                </div>
                            </div>

                            <!-- Monitoramento de conexão (heartbeat) -->
                            <div class="border border-[var(--surface-border)] rounded-lg p-4 bg-[var(--surface-card)] flex flex-col gap-3">
                                <div class="flex items-center justify-between gap-3 flex-wrap">
                                    <div class="flex items-center gap-3">
                                        <div class="grid place-items-center w-10 h-10 rounded-full bg-amber-100 text-amber-600">
                                            <i class="pi pi-heart-fill text-lg" />
                                        </div>
                                        <div>
                                            <div class="font-semibold text-sm">Monitoramento de conexão</div>
                                            <div class="text-xs text-[var(--text-color-secondary)]">
                                                Recebe alerta quando o celular fica offline por mais tempo que o configurado.
                                            </div>
                                        </div>
                                    </div>
                                    <Button icon="pi pi-refresh" size="small" severity="secondary" outlined :loading="incidentsLoading" v-tooltip.bottom="'Recarregar histórico'" @click="loadIncidents" />
                                </div>

                                <div class="grid grid-cols-1 md:grid-cols-[auto_auto_1fr] gap-3 items-end">
                                    <div class="flex items-center gap-2">
                                        <ToggleSwitch v-model="heartbeatConfig.alerts_enabled" inputId="hb-alerts" />
                                        <label for="hb-alerts" class="text-sm cursor-pointer select-none">Alertas ativos</label>
                                    </div>
                                    <div class="flex items-center gap-2">
                                        <label class="text-sm whitespace-nowrap">Alertar após</label>
                                        <InputNumber v-model="heartbeatConfig.threshold_minutes" :min="1" :max="60" showButtons buttonLayout="horizontal" :inputStyle="{ width: '3.5rem', textAlign: 'center' }" incrementButtonIcon="pi pi-plus" decrementButtonIcon="pi pi-minus" />
                                        <span class="text-sm text-[var(--text-color-secondary)]">min sem conexão</span>
                                    </div>
                                    <div class="flex justify-end">
                                        <Button label="Salvar" icon="pi pi-check" size="small" :loading="heartbeatConfigSaving" @click="saveHeartbeatConfig" />
                                    </div>
                                </div>

                                <!-- Reconnect automático -->
                                <div class="flex items-start gap-2 pt-2 border-t border-[var(--surface-border)]">
                                    <ToggleSwitch v-model="heartbeatConfig.reconnect_enabled" inputId="hb-reconnect" />
                                    <label for="hb-reconnect" class="text-sm cursor-pointer select-none flex-1">
                                        <span class="font-semibold">Tentar reconectar automaticamente</span>
                                        <span class="block text-xs text-[var(--text-color-secondary)]">Antes de abrir um alerta, o sistema pede à Evolution pra restaurar a sessão. Se funcionar, ninguém é incomodado. Máximo 1 tentativa a cada 10 minutos.</span>
                                    </label>
                                </div>

                                <!-- Histórico de incidents -->
                                <div class="border-t border-[var(--surface-border)] pt-3">
                                    <div class="text-xs font-semibold uppercase tracking-wide text-[var(--text-color-secondary)] mb-2">
                                        Últimos 7 dias ({{ incidents.length }} {{ incidents.length === 1 ? 'evento' : 'eventos' }})
                                    </div>
                                    <div v-if="incidentsLoading" class="text-xs text-[var(--text-color-secondary)] italic py-3 text-center">
                                        Carregando…
                                    </div>
                                    <div v-else-if="!incidents.length" class="text-xs text-[var(--text-color-secondary)] italic py-3 text-center">
                                        Nenhum evento registrado nos últimos 7 dias — conexão estável.
                                    </div>
                                    <div v-else class="flex flex-col gap-1 max-h-[240px] overflow-y-auto text-xs">
                                        <div v-for="inc in incidents" :key="inc.id"
                                             class="grid grid-cols-[auto_auto_1fr_auto] items-center gap-3 px-2 py-1.5 rounded hover:bg-[var(--surface-hover)]">
                                            <Tag :value="incidentKindLabel(inc.kind)" :severity="incidentKindSeverity(inc.kind)" class="text-[0.62rem]" />
                                            <span :class="inc.resolved_at ? 'text-green-600' : 'text-orange-600'" class="text-[0.62rem] font-bold uppercase">
                                                {{ inc.resolved_at ? 'Resolvido' : 'Aberto' }}
                                            </span>
                                            <span class="text-[var(--text-color-secondary)]">
                                                <span class="font-mono">{{ new Date(inc.started_at).toLocaleString('pt-BR', { dateStyle: 'short', timeStyle: 'short' }) }}</span>
                                                <span v-if="inc.resolved_at"> → {{ new Date(inc.resolved_at).toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' }) }}</span>
                                            </span>
                                            <span class="text-[var(--text-color-secondary)] font-mono">{{ formatDuration(inc.duration_seconds) }}</span>
                                        </div>
                                    </div>
                                </div>
                            </div>

                            <!-- Inbox / CRM de conversas (Fase 5a) -->
                            <div v-if="connectionStatus === 'open'" class="flex flex-col gap-3 px-4 py-3 rounded-lg border border-[var(--surface-border)] bg-[var(--surface-ground)]">
                                <div class="flex items-center justify-between gap-3 flex-wrap">
                                    <div class="flex items-center gap-3">
                                        <div class="grid place-items-center w-10 h-10 rounded-full bg-blue-100 text-blue-600">
                                            <i class="pi pi-inbox text-lg" />
                                        </div>
                                        <div>
                                            <div class="font-semibold text-sm">Inbox de conversas</div>
                                            <div class="text-xs text-[var(--text-color-secondary)]">Receba respostas dos pacientes direto no sistema.</div>
                                        </div>
                                    </div>
                                    <div class="flex gap-2">
                                        <Button label="Conectar inbox" icon="pi pi-link" size="small" :loading="inboxProvisioning" @click="provisionInbox" />
                                        <Button icon="pi pi-external-link" severity="secondary" outlined size="small" v-tooltip.bottom="'Abrir Conversas'" @click="goConversas" />
                                    </div>
                                </div>
                                <div v-if="inboxWebhookUrl" class="text-[0.7rem] text-[var(--text-color-secondary)] bg-[var(--surface-card)] border border-[var(--surface-border)] rounded px-2 py-1.5 font-mono break-all">
                                    Webhook configurado: {{ inboxWebhookUrl }}
                                </div>
                            </div>
                        </template>
                    </div>
                </TabPanel>

                <!-- ══ ABA 2 — Templates ══════════════════════════════════ -->
                <TabPanel :value="1">
                    <div class="flex gap-4 pt-3 items-start">

                        <!-- ── Coluna esquerda: cards de templates (65% no /configuracoes; 100% no /melissa pq a guia vai pro drawer) ── -->
                        <div class="flex flex-col gap-3 min-w-0" :style="inMelissa ? 'flex: 1;' : 'flex: 0 0 65%;'">
                            <!-- Skeleton loading -->
                            <template v-if="templatesLoading">
                                <div v-for="n in 4" :key="n" class="border border-[var(--surface-border)] rounded-xl bg-[var(--surface-card)] p-4">
                                    <div class="flex items-center gap-2 mb-3">
                                        <Skeleton width="5rem" height="1.4rem" border-radius="999px" />
                                        <Skeleton width="10rem" height="1rem" />
                                    </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" border-radius="999px" />
                                    </div>
                                </div>
                            </template>

                            <!-- Cards de templates -->
                            <div v-else v-for="tpl in templates" :key="tpl.key" class="border border-[var(--surface-border)] rounded-xl bg-[var(--surface-card)] p-4 flex flex-col gap-3">
                                <!-- Header do card -->
                                <div class="flex items-center gap-2 flex-wrap">
                                    <span class="font-semibold text-sm">{{ tpl.label }}</span>
                                    <Tag :value="tpl.type" :severity="tpl.type_severity" class="text-[0.65rem]" />
                                    <Tag v-if="tpl.is_custom" value="Personalizado" severity="success" class="text-[0.65rem]" />
                                </div>

                                <!-- Textarea editável -->
                                <Textarea :ref="(el) => setTextareaRef(tpl.key, el)" v-model="tpl.body_text" rows="5" auto-resize class="w-full text-sm font-mono" />

                                <!-- Variáveis clicáveis -->
                                <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 tpl.variables" :key="v" :label="`{{${v}}}`" size="small" severity="secondary" outlined class="font-mono !text-[0.68rem] !py-1 !px-2" @click="insertVariable(tpl.key, v)" />
                                    </div>
                                </div>

                                <!-- Ações -->
                                <div class="flex items-center gap-2 justify-end">
                                    <Button v-if="isTemplateModified(tpl)" label="Restaurar original" icon="pi pi-undo" size="small" severity="secondary" outlined @click="confirmRestoreTemplate(tpl)" />
                                    <Button label="Salvar" icon="pi pi-check" size="small" :loading="templateSaving[tpl.key]" :disabled="templateSaving[tpl.key]" @click="saveTemplate(tpl)" />
                                </div>
                            </div>
                        </div>

                        <!-- ── Coluna direita: guia de formatacao.
                             Em /configuracoes: fica inline (35%).
                             Em /melissa: teleporta pro drawer (#cfg-page-side). -->
                        <Teleport to="#cfg-page-side" :disabled="!inMelissa" defer>
                        <div
                            v-show="!inMelissa || activeTab === 1"
                            class="flex flex-col gap-3"
                            :class="inMelissa ? '' : 'sticky top-4'"
                            :style="inMelissa ? '' : 'flex: 0 0 35%;'"
                        >
                            <div class="border border-[var(--surface-border)] rounded-xl bg-[var(--surface-card)] p-4 flex flex-col gap-4">
                                <div class="flex items-center gap-2">
                                    <i class="pi pi-book text-[var(--primary-color)]" />
                                    <span class="font-semibold text-sm">Guia de formatação</span>
                                </div>

                                <!-- Formatação oficial -->
                                <div class="flex flex-col gap-2">
                                    <div class="flex items-center gap-1.5 mb-1">
                                        <span class="text-[0.7rem] font-semibold uppercase tracking-wider text-[var(--text-color-secondary)]">Formatação oficial</span>
                                        <div class="flex-1 h-px bg-[var(--surface-border)]" />
                                    </div>
                                    <div class="flex flex-col gap-1.5">
                                        <div class="flex items-center justify-between gap-2">
                                            <span class="font-mono text-xs bg-[var(--surface-ground)] px-2 py-0.5 rounded text-[var(--text-color-secondary)]">*texto*</span>
                                            <span class="text-xs font-bold">Negrito</span>
                                        </div>
                                        <div class="flex items-center justify-between gap-2">
                                            <span class="font-mono text-xs bg-[var(--surface-ground)] px-2 py-0.5 rounded text-[var(--text-color-secondary)]">_texto_</span>
                                            <span class="text-xs italic">Itálico</span>
                                        </div>
                                        <div class="flex items-center justify-between gap-2">
                                            <span class="font-mono text-xs bg-[var(--surface-ground)] px-2 py-0.5 rounded text-[var(--text-color-secondary)]">~texto~</span>
                                            <span class="text-xs line-through">Tachado</span>
                                        </div>
                                        <div class="flex items-center justify-between gap-2">
                                            <span class="font-mono text-xs bg-[var(--surface-ground)] px-2 py-0.5 rounded text-[var(--text-color-secondary)]">`texto`</span>
                                            <span class="text-xs font-mono bg-[var(--surface-ground)] px-1 rounded">Monoespaçado</span>
                                        </div>
                                    </div>
                                </div>

                                <!-- Efeitos extras Unicode -->
                                <div class="flex flex-col gap-2">
                                    <div class="flex items-center gap-1.5 mb-1">
                                        <span class="text-[0.7rem] font-semibold uppercase tracking-wider text-[var(--text-color-secondary)]">Efeitos extras (Unicode)</span>
                                        <div class="flex-1 h-px bg-[var(--surface-border)]" />
                                    </div>
                                    <div class="flex flex-col gap-2">
                                        <div class="flex flex-col gap-0.5">
                                            <div class="flex items-center justify-between gap-2">
                                                <span class="text-xs text-[var(--text-color-secondary)]">Negrito Unicode</span>
                                                <span class="text-xs">𝙝𝙤𝙡𝙖</span>
                                            </div>
                                            <span class="text-[0.65rem] text-[var(--text-color-secondary)] opacity-70">Copie de sites de "font generator"</span>
                                        </div>
                                        <div class="flex flex-col gap-0.5">
                                            <div class="flex items-center justify-between gap-2">
                                                <span class="text-xs text-[var(--text-color-secondary)]">Cursiva Unicode</span>
                                                <span class="text-xs">𝓽𝓮𝔁𝓽𝓸</span>
                                            </div>
                                            <span class="text-[0.65rem] text-[var(--text-color-secondary)] opacity-70">Cada letra é um caractere diferente</span>
                                        </div>
                                        <div class="flex flex-col gap-0.5">
                                            <div class="flex items-center justify-between gap-2">
                                                <span class="text-xs text-[var(--text-color-secondary)]">Small Caps</span>
                                                <span class="text-xs">ᴛᴇxᴛᴏ</span>
                                            </div>
                                            <span class="text-[0.65rem] text-[var(--text-color-secondary)] opacity-70">Bom para títulos curtos</span>
                                        </div>
                                        <div class="flex flex-col gap-0.5">
                                            <div class="flex items-center justify-between gap-2">
                                                <span class="text-xs text-[var(--text-color-secondary)]">Sublinhado</span>
                                                <span class="text-xs">t̲e̲x̲t̲o̲</span>
                                            </div>
                                            <span class="text-[0.65rem] text-[var(--text-color-secondary)] opacity-70">U+0332 após cada letra</span>
                                        </div>
                                    </div>
                                </div>

                                <!-- Emojis mais usados -->
                                <div class="flex flex-col gap-2">
                                    <div class="flex items-center gap-1.5 mb-1">
                                        <span class="text-[0.7rem] font-semibold uppercase tracking-wider text-[var(--text-color-secondary)]">Emojis mais usados</span>
                                        <div class="flex-1 h-px bg-[var(--surface-border)]" />
                                    </div>
                                    <div class="flex flex-wrap gap-1">
                                        <button
                                            v-for="emoji in QUICK_EMOJIS"
                                            :key="emoji.char"
                                            v-tooltip.top="emoji.label"
                                            class="text-base leading-none p-1 rounded hover:bg-[var(--surface-hover)] transition-colors cursor-pointer border-0 bg-transparent"
                                            @click="copyEmoji(emoji.char)"
                                        >{{ emoji.char }}</button>
                                    </div>
                                    <span class="text-[0.65rem] text-[var(--text-color-secondary)] opacity-70">Clique para copiar</span>
                                </div>

                                <!-- Dica -->
                                <div class="flex items-start gap-2 px-3 py-2.5 rounded-lg bg-[var(--surface-ground)] border border-[var(--surface-border)]">
                                    <i class="pi pi-lightbulb text-amber-500 text-xs mt-0.5 shrink-0" />
                                    <p class="text-[0.68rem] text-[var(--text-color-secondary)] m-0 leading-relaxed">
                                        Use <strong>*negrito*</strong> para destacar horários e datas. Evite excesso de formatação — mensagens simples têm maior taxa de leitura.
                                    </p>
                                </div>
                            </div>
                        </div>
                        </Teleport>

                    </div>
                </TabPanel>

                <!-- ══ ABA 3 — Logs ═══════════════════════════════════════ -->
                <TabPanel :value="2">
                    <div class="flex flex-col gap-3 pt-3">
                        <!-- Filtros -->
                        <div class="flex items-center gap-2 flex-wrap">
                            <Button
                                v-for="opt in FILTER_OPTIONS"
                                :key="opt.value"
                                :label="opt.label"
                                size="small"
                                :severity="logsFilter === opt.value ? 'primary' : 'secondary'"
                                :outlined="logsFilter !== opt.value"
                                @click="onFilterChange(opt.value)"
                            />
                            <Button icon="pi pi-refresh" size="small" severity="secondary" outlined :loading="logsLoading" v-tooltip.bottom="'Atualizar'" class="ml-auto" @click="loadLogs" />
                        </div>

                        <!-- Tabela -->
                        <DataTable :value="logs" :loading="logsLoading" responsive-layout="scroll" striped-rows class="text-sm">
                            <Column field="created_at" header="Data/hora" style="min-width: 140px">
                                <template #body="{ data }">
                                    {{ formatDate(data.created_at) }}
                                </template>
                            </Column>
                            <Column field="recipient_address" header="Destinatário" style="min-width: 140px" />
                            <Column field="template_key" header="Template" style="min-width: 160px">
                                <template #body="{ data }">
                                    {{ friendlyTemplateKey(data.template_key) }}
                                </template>
                            </Column>
                            <Column field="status" header="Status" style="min-width: 100px">
                                <template #body="{ data }">
                                    <Tag :value="statusTag(data.status).label" :severity="statusTag(data.status).severity" class="text-[0.7rem]" />
                                </template>
                            </Column>
                            <Column field="failure_reason" header="Erro" style="min-width: 160px">
                                <template #body="{ data }">
                                    <span v-if="data.failure_reason" v-tooltip.top="data.failure_reason" class="text-xs text-[var(--text-color-secondary)] truncate block max-w-[200px]">
                                        {{ data.failure_reason }}
                                    </span>
                                    <span v-else class="text-xs text-[var(--text-color-secondary)] opacity-40">—</span>
                                </template>
                            </Column>

                            <template #empty>
                                <div class="text-center py-6 text-sm text-[var(--text-color-secondary)]">Nenhum log de envio encontrado.</div>
                            </template>
                        </DataTable>

                        <!-- Paginação -->
                        <Paginator v-if="logsTotal > logsPerPage" :rows="logsPerPage" :totalRecords="logsTotal" :first="(logsPage - 1) * logsPerPage" @page="onPageChange" />
                    </div>
                </TabPanel>
            </TabPanels>
        </Tabs>

        <!-- ── Dialog QR Code ──────────────────────────────────────── -->
        <Dialog
            v-model:visible="qrDialog"
            modal
            :draggable="false"
            :closable="!qrLoading"
            :dismissableMask="!qrLoading"
            maximizable
            class="dc-dialog w-[36rem]"
            :breakpoints="{ '1199px': '90vw', '768px': '94vw' }"
            :pt="{
                header: { class: '!p-3 !rounded-t-[12px] border-b border-[var(--surface-border)] bg-[var(--surface-ground)]' },
                content: { class: '!p-3' },
                footer: { class: '!p-0 !rounded-b-[12px] border-t border-[var(--surface-border)] bg-[var(--surface-ground)]' },
                pcCloseButton: { root: { class: '!rounded-md hover:!text-red-500' } },
                pcMaximizeButton: { root: { class: '!rounded-md hover:!text-primary' } }
            }"
            pt:mask:class="backdrop-blur-xs"
            @hide="closeQrDialog"
        >
            <template #header>
                <div class="flex w-full items-center justify-between gap-3 px-1">
                    <div class="flex items-center gap-3 min-w-0">
                        <div class="min-w-0">
                            <div class="text-base font-semibold truncate">Conectar WhatsApp</div>
                            <div class="text-xs opacity-50">Escaneie o QR Code para conectar</div>
                        </div>
                    </div>
                </div>
            </template>
            <div class="flex flex-col items-center gap-4 py-2">
                <p class="text-sm text-[var(--text-color-secondary)] text-center m-0">Escaneie o QR Code abaixo com o WhatsApp do seu celular para conectar.</p>

                <!-- Loading -->
                <div v-if="qrLoading" class="flex flex-col items-center gap-3 py-6">
                    <ProgressSpinner style="width: 48px; height: 48px" />
                    <span class="text-xs text-[var(--text-color-secondary)]">Gerando QR Code...</span>
                </div>

                <!-- QR Code -->
                <div v-else-if="qrCodeBase64" class="flex flex-col items-center gap-3">
                    <img :src="qrCodeBase64" alt="QR Code WhatsApp" class="w-64 h-64 rounded-lg border border-[var(--surface-border)]" />
                    <div class="flex items-center gap-2 text-xs text-[var(--text-color-secondary)]">
                        <i class="pi pi-clock" />
                        <span
                            >Atualiza automaticamente em <strong>{{ qrCountdown }}s</strong></span
                        >
                    </div>
                </div>

                <!-- Erro / sem QR -->
                <div v-else class="text-center py-6">
                    <i class="pi pi-exclamation-circle text-3xl text-[var(--text-color-secondary)] opacity-40 mb-2" />
                    <p class="text-sm text-[var(--text-color-secondary)] m-0">Não foi possível gerar o QR Code.</p>
                </div>

                <Button label="Atualizar QR Code" icon="pi pi-refresh" size="small" severity="secondary" outlined :loading="qrLoading" @click="fetchQrCode" />
            </div>

            <template #footer>
                <div class="flex items-center justify-end gap-2 px-3 py-3">
                    <Button label="Fechar" severity="secondary" text class="rounded-full" @click="closeQrDialog" />
                </div>
            </template>
        </Dialog>

        <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>
    </div>
</template>

<style scoped>
</style>
