<!--
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/views/pages/billing/ClinicMeuPlanoPage.vue
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
-->
<script setup>
import { computed, onMounted, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';

import { useToast } from 'primevue/usetoast';

import { supabase } from '@/lib/supabase/client';
import { useTenantStore } from '@/stores/tenantStore';

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

const loading = ref(false);

const subscription = ref(null);
const plan = ref(null);
const price = ref(null);

const features = ref([]); // [{ key, description }]
const events = ref([]); // subscription_events

// ✅ para histórico auditável
const plans = ref([]); // [{id,key,name}]
const profiles = ref([]); // profiles de created_by

const tenantId = computed(() => tenantStore.activeTenantId || tenantStore.tenantId || tenantStore.currentTenantId || null);

// -------------------------
// helpers (format)
// -------------------------
function money(currency, amountCents) {
    if (amountCents == null) return null;
    const value = Number(amountCents) / 100;
    try {
        return new Intl.NumberFormat('pt-BR', { style: 'currency', currency: currency || 'BRL' }).format(value);
    } catch (_) {
        return `${value.toFixed(2)} ${currency || ''}`.trim();
    }
}

function goUpgradeClinic() {
    // ✅ mantém caminho de retorno consistente
    const redirectTo = route?.fullPath || '/admin/meu-plano';
    router.push(`/upgrade?redirectTo=${encodeURIComponent(redirectTo)}`);
}

function fmtDate(iso) {
    if (!iso) return '-';
    const d = new Date(iso);
    if (Number.isNaN(d.getTime())) return String(iso);
    return d.toLocaleString('pt-BR');
}

function prettyMeta(meta) {
    if (!meta) return null;
    try {
        if (typeof meta === 'string') return meta;
        return JSON.stringify(meta, null, 2);
    } catch (_) {
        return String(meta);
    }
}

function statusSeverity(st) {
    const s = String(st || '').toLowerCase();
    if (s === 'active') return 'success';
    if (s === 'trialing') return 'info';
    if (s === 'past_due') return 'warning';
    if (s === 'canceled' || s === 'cancelled') return 'danger';
    if (s === 'incomplete' || s === 'incomplete_expired' || s === 'unpaid') return 'warning';
    return 'secondary';
}

function statusLabelPretty(st) {
    const s = String(st || '').toLowerCase();
    if (s === 'active') return 'Ativa';
    if (s === 'trialing') return 'Trial';
    if (s === 'past_due') return 'Pagamento pendente';
    if (s === 'canceled' || s === 'cancelled') return 'Cancelada';
    if (s === 'unpaid') return 'Não paga';
    if (s === 'incomplete') return 'Incompleta';
    if (s === 'incomplete_expired') return 'Incompleta (expirada)';
    return st || '-';
}

function eventSeverity(t) {
    const k = String(t || '').toLowerCase();
    if (k === 'plan_changed') return 'info';
    if (k === 'canceled') return 'danger';
    if (k === 'reactivated') return 'success';
    if (k === 'created') return 'secondary';
    if (k === 'status_changed') return 'warning';
    return 'secondary';
}

function eventLabel(t) {
    const k = String(t || '').toLowerCase();
    if (k === 'plan_changed') return 'Plano alterado';
    if (k === 'canceled') return 'Cancelada';
    if (k === 'reactivated') return 'Reativada';
    if (k === 'created') return 'Criada';
    if (k === 'status_changed') return 'Status alterado';
    return t || '-';
}

// -------------------------
// helpers (plans / profiles)
// -------------------------
const planById = computed(() => {
    const m = new Map();
    for (const p of plans.value || []) m.set(String(p.id), p);
    return m;
});

function planKeyOrName(planId) {
    if (!planId) return '—';
    const p = planById.value.get(String(planId));
    return p?.key || p?.name || String(planId);
}

const profileById = computed(() => {
    const m = new Map();
    for (const p of profiles.value || []) m.set(String(p.id), p);
    return m;
});

function displayUser(userId) {
    if (!userId) return '—';
    const p = profileById.value.get(String(userId));
    if (!p) return String(userId);

    const name = p.nome || p.name || p.full_name || p.display_name || p.username || null;
    const email = p.email || p.email_principal || p.user_email || null;

    if (name && email) return `${name} <${email}>`;
    if (name) return name;
    if (email) return email;
    return String(userId);
}

// -------------------------
// computed (header info)
// -------------------------
const planName = computed(() => plan.value?.name || subscription.value?.plan_key || '-');
const statusLabel = computed(() => subscription.value?.status || '-');
const statusLabelPrettyComputed = computed(() => statusLabelPretty(subscription.value?.status));

const intervalLabel = computed(() => {
    const i = subscription.value?.interval;
    if (i === 'month') return 'mês';
    if (i === 'year') return 'ano';
    return i || '-';
});

const priceLabel = computed(() => {
    if (!price.value) return null;
    return `${money(price.value.currency, price.value.amount_cents)} / ${intervalLabel.value}`;
});

const periodLabel = computed(() => {
    const s = subscription.value;
    if (!s?.current_period_start || !s?.current_period_end) return '-';
    return `${fmtDate(s.current_period_start)} → ${fmtDate(s.current_period_end)}`;
});

const cancelHint = computed(() => {
    const s = subscription.value;
    if (!s) return null;
    if (s.cancel_at_period_end) {
        const end = s.current_period_end ? fmtDate(s.current_period_end) : null;
        return end ? `Cancelamento no fim do período (${end}).` : 'Cancelamento no fim do período.';
    }
    if (s.canceled_at) return `Cancelada em ${fmtDate(s.canceled_at)}.`;
    return null;
});

// -------------------------
// ✅ agrupamento de features por módulo (prefixo)
// -------------------------
function moduleFromKey(key) {
    const k = String(key || '').trim();
    if (!k) return 'Outros';

    // tenta por "."
    if (k.includes('.')) {
        const head = k.split('.')[0];
        return head || 'Outros';
    }

    // tenta por "_"
    if (k.includes('_')) {
        const head = k.split('_')[0];
        return head || 'Outros';
    }

    return 'Outros';
}

function moduleLabel(m) {
    const s = String(m || '').trim();
    if (!s) return 'Outros';
    return s.charAt(0).toUpperCase() + s.slice(1);
}

const groupedFeatures = computed(() => {
    const list = features.value || [];
    const map = new Map();

    for (const f of list) {
        const mod = moduleFromKey(f.key);
        if (!map.has(mod)) map.set(mod, []);
        map.get(mod).push(f);
    }

    // ordena módulos e itens
    const modules = Array.from(map.keys()).sort((a, b) => {
        if (a === 'Outros') return 1;
        if (b === 'Outros') return -1;
        return a.localeCompare(b);
    });

    return modules.map((mod) => {
        const items = map.get(mod) || [];
        items.sort((a, b) => String(a.key || '').localeCompare(String(b.key || '')));
        return { module: mod, items };
    });
});

// -------------------------
// fetch
// -------------------------
async function fetchMeuPlanoClinic() {
    loading.value = true;
    try {
        const tid = tenantId.value;
        if (!tid) throw new Error('Tenant ativo não encontrado.');

        // 1) assinatura do tenant (prioriza status "ativo" e afins; cai pro mais recente)
        // ✅ depois das mudanças: não assume só "active" (pode estar trialing/past_due etc.)
        const sRes = await supabase.from('subscriptions').select('*').eq('tenant_id', tid).order('created_at', { ascending: false }).limit(10);

        if (sRes.error) throw sRes.error;

        const list = sRes.data || [];
        const priority = (st) => {
            const s = String(st || '').toLowerCase();
            if (s === 'active') return 1;
            if (s === 'trialing') return 2;
            if (s === 'past_due') return 3;
            if (s === 'unpaid') return 4;
            if (s === 'incomplete') return 5;
            if (s === 'canceled' || s === 'cancelled') return 9;
            return 8;
        };

        subscription.value =
            list.slice().sort((a, b) => {
                const pa = priority(a?.status);
                const pb = priority(b?.status);
                if (pa !== pb) return pa - pb;
                // empate: mais recente
                return new Date(b?.created_at || 0) - new Date(a?.created_at || 0);
            })[0] || null;

        if (!subscription.value) {
            plan.value = null;
            price.value = null;
            features.value = [];
            events.value = [];
            plans.value = [];
            profiles.value = [];
            return;
        }

        // 2) plano (atual)
        if (subscription.value.plan_id) {
            const pRes = await supabase.from('plans').select('id, key, name, description').eq('id', subscription.value.plan_id).maybeSingle();

            if (pRes.error) throw pRes.error;
            plan.value = pRes.data || null;
        } else {
            plan.value = null;
        }

        // 3) preço vigente (intervalo atual)
        // ✅ robustez: tenta preço vigente por janela; se não achar, pega o último ativo do intervalo
        price.value = null;
        if (subscription.value.plan_id && subscription.value.interval) {
            const nowIso = new Date().toISOString();

            const ppRes = await supabase
                .from('plan_prices')
                .select('currency, interval, amount_cents, is_active, active_from, active_to')
                .eq('plan_id', subscription.value.plan_id)
                .eq('interval', subscription.value.interval)
                .eq('is_active', true)
                .lte('active_from', nowIso)
                .or(`active_to.is.null,active_to.gte.${nowIso}`)
                .order('active_from', { ascending: false })
                .limit(1)
                .maybeSingle();

            if (ppRes.error) throw ppRes.error;
            price.value = ppRes.data || null;

            if (!price.value) {
                const ppFallback = await supabase
                    .from('plan_prices')
                    .select('currency, interval, amount_cents, is_active, active_from, active_to')
                    .eq('plan_id', subscription.value.plan_id)
                    .eq('interval', subscription.value.interval)
                    .eq('is_active', true)
                    .order('active_from', { ascending: false })
                    .limit(1)
                    .maybeSingle();

                if (ppFallback.error) throw ppFallback.error;
                price.value = ppFallback.data || null;
            }
        }

        // 4) features do plano
        features.value = [];
        if (subscription.value.plan_id) {
            const pfRes = await supabase.from('plan_features').select('feature_id').eq('plan_id', subscription.value.plan_id);

            if (pfRes.error) throw pfRes.error;

            const featureIds = (pfRes.data || []).map((r) => r.feature_id).filter(Boolean);
            if (featureIds.length) {
                const fRes = await supabase.from('features').select('id, key, description, descricao').in('id', featureIds).order('key', { ascending: true });

                if (fRes.error) throw fRes.error;

                features.value = (fRes.data || []).map((f) => ({
                    key: f.key,
                    description: (f.descricao || f.description || '').trim()
                }));
            }
        }

        // 5) histórico (50) — se existir subscription_id
        events.value = [];
        if (subscription.value?.id) {
            const eRes = await supabase.from('subscription_events').select('*').eq('subscription_id', subscription.value.id).order('created_at', { ascending: false }).limit(50);

            if (eRes.error) throw eRes.error;
            events.value = eRes.data || [];
        }

        // ✅ 6) pré-carrega planos citados em (old/new) + plano atual
        const planIds = new Set();
        if (subscription.value?.plan_id) planIds.add(String(subscription.value.plan_id));

        for (const ev of events.value) {
            if (ev?.old_plan_id) planIds.add(String(ev.old_plan_id));
            if (ev?.new_plan_id) planIds.add(String(ev.new_plan_id));
        }

        if (planIds.size) {
            const { data: pAll, error: epAll } = await supabase.from('plans').select('id,key,name').in('id', Array.from(planIds));

            plans.value = epAll ? [] : pAll || [];
        } else {
            plans.value = [];
        }

        // ✅ 7) perfis (created_by)
        const userIds = new Set();
        for (const ev of events.value) {
            const by = String(ev.created_by || '').trim();
            if (by) userIds.add(by);
        }

        if (userIds.size) {
            const { data: pr, error: epr } = await supabase.from('profiles').select('*').in('id', Array.from(userIds));

            profiles.value = epr ? [] : pr || [];
        } else {
            profiles.value = [];
        }
    } catch (e) {
        console.error(e);
        toast.add({ severity: 'error', summary: 'Erro', detail: e?.message || String(e), life: 5000 });
    } finally {
        loading.value = false;
    }
}

onMounted(fetchMeuPlanoClinic);
</script>

<template>
    <!-- Sentinel -->
    <div class="h-px" />

    <!-- ══════════════════════════════════════════════════════
       HERO sticky
  ═══════════════════════════════════════════════════════ -->
    <section class="sticky mx-3 md:mx-4 my-3 z-20 overflow-hidden rounded-md border border-[var(--surface-border,#e2e8f0)] bg-[var(--surface-card,#fff)] px-3 py-2.5" :style="{ top: 'var(--layout-sticky-top, 56px)' }">
        <!-- Blobs -->
        <div class="absolute inset-0 pointer-events-none overflow-hidden" aria-hidden="true">
            <div class="absolute w-64 h-64 -top-16 -right-8 rounded-full blur-[60px] bg-indigo-500/10" />
            <div class="absolute w-72 h-72 top-0 -left-16 rounded-full blur-[60px] bg-emerald-400/[0.08]" />
        </div>

        <div class="relative z-1 flex items-center gap-3">
            <!-- Brand -->
            <div class="flex items-center gap-2 shrink-0">
                <div class="grid place-items-center w-9 h-9 rounded-md shrink-0 bg-indigo-500/10 text-indigo-500">
                    <i class="pi pi-credit-card text-base" />
                </div>
                <div class="min-w-0 hidden sm:block">
                    <div class="text-[1rem] font-bold tracking-tight text-[var(--text-color)]">Meu Plano</div>
                    <div class="text-[1rem] text-[var(--text-color-secondary)]">Plano da clínica (tenant) e recursos habilitados</div>
                </div>
            </div>

            <!-- Ações desktop -->
            <div class="hidden sm:flex items-center gap-1 shrink-0 ml-auto">
                <Button icon="pi pi-refresh" severity="secondary" outlined class="h-9 w-9 rounded-full shrink-0" :loading="loading" title="Atualizar" @click="fetchMeuPlanoClinic" />
                <Button label="Alterar plano" icon="pi pi-arrow-up-right" class="rounded-full" @click="goUpgradeClinic" />
            </div>

            <!-- Ações mobile -->
            <div class="flex sm:hidden items-center gap-1 shrink-0 ml-auto">
                <Button icon="pi pi-refresh" severity="secondary" outlined class="h-9 w-9 rounded-full shrink-0" :loading="loading" @click="fetchMeuPlanoClinic" />
                <Button label="Upgrade" icon="pi pi-arrow-up-right" size="small" class="rounded-full" @click="goUpgradeClinic" />
            </div>
        </div>
    </section>

    <!-- ══════════════════════════════════════════════════════
       QUICK-STATS
  ═══════════════════════════════════════════════════════ -->
    <div class="flex flex-wrap gap-2 px-3 md:px-4 mb-3">
        <div class="flex flex-col gap-0.5 px-4 py-2.5 rounded-md border flex-1 min-w-[80px] border-[var(--surface-border,#e2e8f0)] bg-[var(--surface-card,#fff)]">
            <div class="text-[1.1rem] font-bold leading-none text-[var(--text-color)] truncate">{{ planName }}</div>
            <div class="text-[1rem] text-[var(--text-color-secondary)] opacity-75">Plano atual</div>
        </div>
        <div
            class="flex flex-col gap-0.5 px-4 py-2.5 rounded-md border flex-1 min-w-[80px] transition-colors duration-150"
            :class="subscription?.status === 'active' ? 'border-green-500/25 bg-green-500/5' : 'border-[var(--surface-border,#e2e8f0)] bg-[var(--surface-card,#fff)]'"
        >
            <div class="text-[1.1rem] font-bold leading-none truncate" :class="subscription?.status === 'active' ? 'text-green-500' : 'text-[var(--text-color)]'">{{ statusLabelPrettyComputed }}</div>
            <div class="text-[1rem] text-[var(--text-color-secondary)] opacity-75">Status</div>
        </div>
        <div class="flex flex-col gap-0.5 px-4 py-2.5 rounded-md border flex-1 min-w-[80px] border-[var(--surface-border,#e2e8f0)] bg-[var(--surface-card,#fff)]">
            <div class="text-[1.35rem] font-bold leading-none text-[var(--text-color)]">{{ features.length }}</div>
            <div class="text-[1rem] text-[var(--text-color-secondary)] opacity-75">Recursos</div>
        </div>
        <div class="flex flex-col gap-0.5 px-4 py-2.5 rounded-md border flex-1 min-w-[80px] border-[var(--surface-border,#e2e8f0)] bg-[var(--surface-card,#fff)]">
            <div class="text-[1.35rem] font-bold leading-none text-[var(--text-color)]">{{ events.length }}</div>
            <div class="text-[1rem] text-[var(--text-color-secondary)] opacity-75">Eventos</div>
        </div>
    </div>

    <!-- ══════════════════════════════════════════════════════
       CONTEÚDO
  ═══════════════════════════════════════════════════════ -->
    <div class="px-3 md:px-4 pb-8">
        <!-- Loading skeleton -->
        <div v-if="loading" class="flex flex-col gap-3">
            <div v-for="n in 3" :key="n" class="flex items-center gap-4 p-4 rounded-md border border-[var(--surface-border,#e2e8f0)] bg-[var(--surface-card,#fff)]">
                <div class="w-10 h-10 rounded-full shrink-0 bg-[var(--surface-border,#e2e8f0)] animate-pulse" />
                <div class="flex flex-col gap-2 flex-1">
                    <div class="h-3.5 w-3/5 rounded-md bg-[var(--surface-border,#e2e8f0)] animate-pulse" />
                    <div class="h-2.5 w-2/5 rounded-md bg-[var(--surface-border,#e2e8f0)] animate-pulse" />
                </div>
            </div>
        </div>

        <!-- Empty state: sem assinatura -->
        <div v-else-if="!subscription" class="flex flex-col items-center justify-center gap-4 rounded-md border-2 border-dashed border-[var(--surface-border,#e2e8f0)] bg-[var(--surface-ground,#f8fafc)] py-16 px-6 text-center">
            <div class="relative">
                <div class="grid place-items-center w-16 h-16 rounded-2xl bg-[var(--surface-card,#fff)] border border-[var(--surface-border,#e2e8f0)] shadow-sm text-[var(--text-color-secondary)]">
                    <i class="pi pi-credit-card text-3xl opacity-30" />
                </div>
                <div class="absolute -top-2 -right-2 w-7 h-7 rounded-full bg-[var(--surface-card,#fff)] border border-[var(--surface-border,#e2e8f0)] shadow-sm grid place-items-center">
                    <i class="pi pi-times text-[0.65rem] text-[var(--text-color-secondary)] opacity-50" />
                </div>
            </div>
            <div>
                <div class="font-bold text-[1rem] text-[var(--text-color)] mb-1">Nenhuma assinatura encontrada</div>
                <div class="text-[1rem] text-[var(--text-color-secondary)] max-w-xs leading-relaxed">Nenhuma assinatura foi encontrada para este tenant.</div>
            </div>
            <Button label="Ver planos" icon="pi pi-arrow-up-right" class="rounded-full mt-1" @click="goUpgradeClinic" />
        </div>

        <!-- Conteúdo com assinatura -->
        <div v-else class="flex flex-col gap-3">
            <!-- ── Assinatura atual ──────────────────────────── -->
            <div class="rounded-md border border-[var(--surface-border,#e2e8f0)] bg-[var(--surface-card,#fff)] overflow-hidden">
                <div class="flex items-center justify-between px-4 py-3 border-b border-[var(--surface-border,#e2e8f0)]">
                    <div class="flex items-center gap-2">
                        <i class="pi pi-credit-card text-[var(--text-color-secondary)] opacity-60" />
                        <span class="font-semibold text-[1rem]">Assinatura atual</span>
                    </div>
                    <div class="flex items-center gap-2">
                        <Tag :value="statusLabelPrettyComputed" :severity="statusSeverity(subscription?.status)" />
                        <Tag v-if="subscription?.cancel_at_period_end" severity="warning" value="Cancelamento agendado" />
                        <Tag v-else severity="success" value="Renovação automática" />
                    </div>
                </div>

                <div class="px-4 py-3 flex flex-wrap gap-x-8 gap-y-3">
                    <div class="flex flex-col gap-0.5">
                        <span class="text-[0.68rem] font-bold uppercase tracking-[0.06em] text-[var(--text-color-secondary)] opacity-60">Plano</span>
                        <span class="text-[0.9rem] font-semibold text-[var(--text-color)]">{{ planName }}</span>
                    </div>
                    <div class="flex flex-col gap-0.5">
                        <span class="text-[0.68rem] font-bold uppercase tracking-[0.06em] text-[var(--text-color-secondary)] opacity-60">Valor</span>
                        <span class="text-[1rem] text-[var(--text-color)]">{{ priceLabel || 'Preço não encontrado para este intervalo.' }}</span>
                    </div>
                    <div class="flex flex-col gap-0.5">
                        <span class="text-[0.68rem] font-bold uppercase tracking-[0.06em] text-[var(--text-color-secondary)] opacity-60">Período</span>
                        <span class="text-[1rem] text-[var(--text-color)]">{{ periodLabel }}</span>
                    </div>
                    <div v-if="cancelHint" class="flex flex-col gap-0.5 w-full">
                        <span class="text-[0.68rem] font-bold uppercase tracking-[0.06em] text-[var(--text-color-secondary)] opacity-60">Atenção</span>
                        <span class="text-[1rem] text-[var(--text-color-secondary)]">{{ cancelHint }}</span>
                    </div>
                    <div v-if="plan?.description" class="flex flex-col gap-0.5 w-full">
                        <span class="text-[0.68rem] font-bold uppercase tracking-[0.06em] text-[var(--text-color-secondary)] opacity-60">Descrição</span>
                        <span class="text-[1rem] text-[var(--text-color-secondary)]">{{ plan.description }}</span>
                    </div>
                    <div class="flex flex-col gap-0.5">
                        <span class="text-[0.68rem] font-bold uppercase tracking-[0.06em] text-[var(--text-color-secondary)] opacity-60">ID da assinatura</span>
                        <code class="text-[0.75rem] text-[var(--text-color-secondary)] break-all font-mono select-all">{{ subscription.id }}</code>
                    </div>
                </div>
            </div>

            <div class="grid grid-cols-1 lg:grid-cols-2 gap-3">
                <!-- ── Features agrupadas ─────────────────────── -->
                <div class="rounded-md border border-[var(--surface-border,#e2e8f0)] bg-[var(--surface-card,#fff)] overflow-hidden">
                    <div class="flex items-center justify-between px-4 py-3 border-b border-[var(--surface-border,#e2e8f0)]">
                        <div class="flex items-center gap-2">
                            <i class="pi pi-check-circle text-[var(--text-color-secondary)] opacity-60" />
                            <span class="font-semibold text-[1rem]">Seu plano inclui</span>
                        </div>
                        <span v-if="features.length" class="inline-flex items-center justify-center min-w-[22px] h-[22px] px-1.5 rounded-full bg-[var(--primary-color,#6366f1)] text-white text-[1rem] font-bold">{{ features.length }}</span>
                    </div>

                    <div class="p-4">
                        <div v-if="!features.length" class="text-[1rem] text-[var(--text-color-secondary)]">Nenhuma feature vinculada a este plano.</div>

                        <div v-else class="flex flex-col gap-5">
                            <div v-for="g in groupedFeatures" :key="g.module">
                                <!-- Cabeçalho do módulo -->
                                <div class="flex items-center gap-2 mb-2">
                                    <span class="text-[0.68rem] font-bold uppercase tracking-[0.07em] text-[var(--text-color-secondary)] opacity-50">{{ moduleLabel(g.module) }}</span>
                                    <div class="flex-1 h-px bg-[var(--surface-border,#e2e8f0)]" />
                                    <span class="text-[1rem] text-[var(--text-color-secondary)]">{{ g.items.length }}</span>
                                </div>
                                <!-- Grid de features -->
                                <div class="grid grid-cols-1 sm:grid-cols-2 gap-x-4 gap-y-1">
                                    <div v-for="f in g.items" :key="f.key" class="flex items-start gap-2 py-1 px-2 rounded-md hover:bg-[var(--surface-ground,#f8fafc)] transition-colors" :title="f.description || f.key">
                                        <i class="pi pi-check-circle text-emerald-500 text-[1rem] mt-0.5 shrink-0" />
                                        <div class="min-w-0">
                                            <div class="text-[1rem] font-medium truncate text-[var(--text-color)]">{{ f.key }}</div>
                                            <div v-if="f.description" class="text-[1rem] text-[var(--text-color-secondary)] leading-snug truncate">{{ f.description }}</div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            <div class="text-[1rem] text-[var(--text-color-secondary)] opacity-60">Agrupamento automático por prefixo da key (ex.: <b>agenda.*</b>, <b>patients.*</b>).</div>
                        </div>
                    </div>
                </div>

                <!-- ── Histórico ──────────────────────────────── -->
                <div class="rounded-md border border-[var(--surface-border,#e2e8f0)] bg-[var(--surface-card,#fff)] overflow-hidden">
                    <div class="flex items-center justify-between px-4 py-3 border-b border-[var(--surface-border,#e2e8f0)]">
                        <div class="flex items-center gap-2">
                            <i class="pi pi-history text-[var(--text-color-secondary)] opacity-60" />
                            <span class="font-semibold text-[1rem]">Histórico</span>
                        </div>
                        <span v-if="events.length" class="inline-flex items-center justify-center min-w-[22px] h-[22px] px-1.5 rounded-full bg-[var(--primary-color,#6366f1)] text-white text-[1rem] font-bold">{{ events.length }}</span>
                    </div>

                    <div class="p-4">
                        <div v-if="!events.length" class="py-8 text-center">
                            <i class="pi pi-history text-2xl text-[var(--text-color-secondary)] opacity-20 mb-2 block" />
                            <div class="text-[1rem] text-[var(--text-color-secondary)]">Sem eventos registrados.</div>
                        </div>

                        <div v-else class="flex flex-col gap-2">
                            <div v-for="ev in events" :key="ev.id" class="rounded-md border border-[var(--surface-border,#e2e8f0)] p-3 hover:bg-[var(--surface-ground,#f8fafc)] transition-colors duration-100">
                                <div class="flex items-start justify-between gap-3 flex-wrap">
                                    <div class="min-w-0 flex-1">
                                        <div class="flex items-center gap-2 flex-wrap">
                                            <Tag :value="eventLabel(ev.event_type)" :severity="eventSeverity(ev.event_type)" />
                                            <span class="text-[1rem] text-[var(--text-color-secondary)]">
                                                por <b>{{ displayUser(ev.created_by) }}</b>
                                            </span>
                                        </div>
                                        <div v-if="ev.old_plan_id || ev.new_plan_id" class="mt-1.5 text-[1rem] text-[var(--text-color-secondary)] flex items-center gap-1.5 flex-wrap">
                                            <span class="font-medium text-[var(--text-color)]">{{ planKeyOrName(ev.old_plan_id) }}</span>
                                            <i class="pi pi-arrow-right text-[1rem] opacity-50" />
                                            <span class="font-medium text-[var(--text-color)]">{{ planKeyOrName(ev.new_plan_id) }}</span>
                                        </div>
                                        <div v-if="ev.reason" class="mt-1 text-[1rem] text-[var(--text-color-secondary)] opacity-70">{{ ev.reason }}</div>
                                        <div v-if="ev.metadata" class="mt-1.5">
                                            <pre class="m-0 text-[1rem] text-[var(--text-color-secondary)] whitespace-pre-wrap break-words opacity-60">{{ prettyMeta(ev.metadata) }}</pre>
                                        </div>
                                    </div>
                                    <div class="text-[1rem] text-[var(--text-color-secondary)] shrink-0">{{ fmtDate(ev.created_at) }}</div>
                                </div>
                            </div>
                            <div class="text-[1rem] text-[var(--text-color-secondary)] opacity-60 mt-1">Mostrando até 50 eventos (mais recentes).</div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>
