<script setup>
/*
 * MelissaPlano — Pagina nativa Melissa pra "Meu Plano".
 *
 * Substitui o embed cfg-plano que vivia dentro do MelissaConfiguracoes.
 * Layout 2-col (espelha MelissaPerfil):
 *   - COL 1 (sidebar) — Card "Plano atual" (nome + status + valor +
 *     periodo + ID) + Card "Resumo" (mini-stats: recursos, eventos,
 *     proxima renovacao) + Footer com CTAs (Alterar plano + Atualizar)
 *   - COL 2 (main) — Card "Seu plano inclui" (features agrupadas por
 *     modulo) + Card "Historico" (subscription_events com badges).
 *
 * Logica de fetch espelhada de TherapistMeuPlanoPage.vue (subscriptions
 * + plans + plan_prices + plan_features + features + subscription_events
 * + profiles).
 */
import { ref, computed, onMounted } from 'vue';
import MelissaConfigList from './MelissaConfigList.vue';
import { useRouter } from 'vue-router';
import { useToast } from 'primevue/usetoast';
import { supabase } from '@/lib/supabase/client';
import { useTenantStore } from '@/stores/tenantStore';
// Tag/Skeleton: auto via PrimeVueResolver

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

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

// ── Breakpoints + drawer ───────────────────────────────────
const drawerOpen = ref(false);
const isMobile = ref(false);
let _mqMobile = null;
function _onMqMobileChange(e) {
    isMobile.value = e.matches;
    if (!e.matches) drawerOpen.value = false;
}
function toggleDrawer() { drawerOpen.value = !drawerOpen.value; }
function fecharDrawer() { drawerOpen.value = false; }

// Toggle entre cards (default) e lista de configs (alterna inline na sidebar)
const cfgOpen = ref(false);
function toggleCfg() { cfgOpen.value = !cfgOpen.value; }
function fecharCfg() { cfgOpen.value = false; }

// ── Estado ─────────────────────────────────────────────────
const loading = ref(false);
const hasLoaded = ref(false);
const subscription = ref(null);
const plan = ref(null);
const price = ref(null);
const features = ref([]);
const events = ref([]);
const plans = ref([]);
const profiles = ref([]);

// ── Formatters ─────────────────────────────────────────────
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 fmtDate(iso) {
    if (!iso) return '—';
    const d = new Date(iso);
    if (Number.isNaN(d.getTime())) return String(iso);
    return d.toLocaleString('pt-BR');
}
function fmtDateShort(iso) {
    if (!iso) return '—';
    const d = new Date(iso);
    if (Number.isNaN(d.getTime())) return String(iso);
    return d.toLocaleDateString('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';
    return 'secondary';
}
function statusLabel(st) {
    const s = String(st || '').toLowerCase();
    if (s === 'active') return 'Ativo';
    if (s === 'trialing') return 'Trial';
    if (s === 'past_due') return 'Atrasado';
    if (s === 'canceled' || s === 'cancelled') return 'Cancelado';
    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';
    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';
    return t || '—';
}

// ── Computed ───────────────────────────────────────────────
const planName = computed(() => plan.value?.name || subscription.value?.plan_key || '—');
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 `${fmtDateShort(s.current_period_start)} → ${fmtDateShort(s.current_period_end)}`;
});
const renewLabel = computed(() => {
    const s = subscription.value;
    if (!s?.current_period_end) return '—';
    return fmtDateShort(s.current_period_end);
});

// ── Features agrupadas ─────────────────────────────────────
function moduleFromKey(key) {
    const k = String(key || '').trim();
    if (!k) return 'Outros';
    if (k.includes('.')) return k.split('.')[0] || 'Outros';
    if (k.includes('_')) return k.split('_')[0] || '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);
    }
    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 };
    });
});

// ── Historico ──────────────────────────────────────────────
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 || null;
    const email = p.email || p.email_principal || null;
    if (name && email) return `${name} <${email}>`;
    return name || email || String(userId);
}

// ── Actions ────────────────────────────────────────────────
function goUpgrade() {
    // Vai pra pagina nativa Melissa de alterar plano (substitui o
    // /therapist/upgrade que virava redirect e perdia o overlay Melissa).
    router.push({ name: 'Melissa', params: { secao: 'alterar-plano' } });
}

// ── Fetch ──────────────────────────────────────────────────
async function fetchMeuPlano() {
    loading.value = true;
    try {
        const { data: authData, error: authError } = await supabase.auth.getUser();
        if (authError) throw authError;
        const uid = authData?.user?.id;
        if (!uid) throw new Error('Sessão não encontrada.');

        const sRes = await supabase
            .from('subscriptions')
            .select('*')
            .eq('user_id', uid)
            .order('created_at', { ascending: false })
            .limit(10);
        if (sRes.error) throw sRes.error;

        const subList = 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 = subList.length
            ? subList.slice().sort((a, b) => {
                  const pa = priority(a?.status);
                  const pb = priority(b?.status);
                  if (pa !== pb) return pa - pb;
                  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;
        }

        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;

        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;

        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()
            }));
        } else {
            features.value = [];
        }

        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 || [];

        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 = [];
        }

        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) {
        toast.add({ severity: 'error', summary: 'Erro', detail: e?.message || String(e), life: 5000 });
    } finally {
        loading.value = false;
        hasLoaded.value = true;
    }
}

// ── Lifecycle ──────────────────────────────────────────────
onMounted(async () => {
    if (typeof window !== 'undefined' && window.matchMedia) {
        _mqMobile = window.matchMedia('(max-width: 1023px)');
        isMobile.value = _mqMobile.matches;
        try { _mqMobile.addEventListener('change', _onMqMobileChange); }
        catch { _mqMobile.addListener(_onMqMobileChange); }
    }
    await tenantStore.ensureLoaded();
    await fetchMeuPlano();
});
</script>

<template>
    <Transition name="mpl-drawer-fade">
        <div
            v-show="isMobile && drawerOpen"
            class="mpl-mobile-drawer"
            :class="{ 'is-open': drawerOpen }"
        >
            <div id="mpl-mobile-drawer-target" class="mpl-mobile-drawer__scroll" />
        </div>
    </Transition>
    <Transition name="mpl-drawer-fade">
        <div
            v-show="isMobile && drawerOpen"
            class="mpl-mobile-drawer__backdrop"
            @click="fecharDrawer"
        />
    </Transition>

    <section class="mpl-page">
        <header class="mpl-page__head">
            <button
                class="mpl-menu-btn mpl-menu-btn--mobile-only"
                v-tooltip.bottom="'Plano & Acoes'"
                @click="toggleDrawer"
            >
                <i class="pi pi-bars" />
                <span>Menu Plano</span>
            </button>
            <div class="mpl-page__title">
                <i class="pi pi-credit-card mpl-page__title-icon" />
                <span>Meu Plano</span>
                <Tag
                    v-if="subscription"
                    :value="statusLabel(subscription.status)"
                    :severity="statusSeverity(subscription.status)"
                />
            </div>
            <div class="mpl-page__actions">
                <button
                    class="mpl-act-btn"
                    v-tooltip.bottom="'Atualizar'"
                    :disabled="loading"
                    @click="fetchMeuPlano"
                >
                    <i :class="loading ? 'pi pi-spin pi-spinner' : 'pi pi-refresh'" />
                </button>
                <button class="mpl-close" v-tooltip.bottom="'Voltar (Esc)'" @click="emit('close')">
                    <i class="pi pi-times" />
                </button>
            </div>
        </header>

        <div class="mpl-subheader">
            <i class="pi pi-info-circle mpl-subheader__icon" />
            <span class="mpl-subheader__text">
                Sua assinatura, recursos inclusos e histórico de mudanças. Pra trocar
                de plano, clique em <strong>Alterar plano</strong> na lateral.
            </span>
        </div>

        <div class="mpl-body">
            <!-- ═══ COL 1: Sidebar ═══ -->
            <Teleport to="#mpl-mobile-drawer-target" :disabled="!isMobile">
                <aside class="mpl-side">
                    <button class="mpl-cfg-btn" :class="{ 'is-open': cfgOpen }" @click="toggleCfg">
                        <i :class="cfgOpen ? 'pi pi-arrow-left' : 'pi pi-cog'" />
                        <span>{{ cfgOpen ? 'Voltar' : 'Configurações' }}</span>
                        <i v-if="!cfgOpen" class="pi pi-chevron-down mpl-cfg-btn__chev" />
                    </button>
                    <div v-if="cfgOpen" class="mpl-side__scroll mpl-side__scroll--cfg">
                        <MelissaConfigList @select="fecharCfg" />
                    </div>
                    <div v-else class="mpl-side__scroll">
                        <!-- Card: Plano atual -->
                        <div class="mpl-w mpl-w--side">
                            <div class="mpl-w__head">
                                <div class="mpl-w__icon"><i class="pi pi-credit-card" /></div>
                                <div class="mpl-w__title">
                                    <div class="mpl-w__title-text">Plano atual</div>
                                    <div class="mpl-w__sub">Assinatura ativa e ciclo de cobrança</div>
                                </div>
                            </div>

                            <div class="mpl-w__body">
                                <template v-if="loading && !hasLoaded">
                                    <Skeleton width="60%" height="22px" class="mb-2" />
                                    <Skeleton width="100%" height="14px" class="mb-1" />
                                    <Skeleton width="80%" height="14px" />
                                </template>

                                <template v-else-if="!subscription">
                                    <div class="mpl-empty">
                                        <i class="pi pi-credit-card mpl-empty__icon" />
                                        <div class="mpl-empty__title">Nenhuma assinatura</div>
                                        <div class="mpl-empty__hint">
                                            Escolha um plano pra começar.
                                        </div>
                                    </div>
                                </template>

                                <template v-else>
                                    <div class="mpl-plan">
                                        <div class="mpl-plan__name">{{ planName }}</div>
                                        <div class="mpl-plan__price">
                                            {{ priceLabel || 'Preço não disponível' }}
                                        </div>
                                    </div>

                                    <div class="mpl-info">
                                        <div class="mpl-info__row">
                                            <span class="mpl-info__label">Status</span>
                                            <Tag
                                                :value="statusLabel(subscription.status)"
                                                :severity="statusSeverity(subscription.status)"
                                            />
                                        </div>
                                        <div class="mpl-info__row">
                                            <span class="mpl-info__label">Ciclo atual</span>
                                            <span class="mpl-info__value">{{ periodLabel }}</span>
                                        </div>
                                        <div class="mpl-info__row">
                                            <span class="mpl-info__label">
                                                {{ subscription.cancel_at_period_end ? 'Encerra em' : 'Renova em' }}
                                            </span>
                                            <span class="mpl-info__value">{{ renewLabel }}</span>
                                        </div>
                                        <div class="mpl-info__row">
                                            <span class="mpl-info__label">Renovação</span>
                                            <Tag
                                                v-if="subscription.cancel_at_period_end"
                                                value="Cancelamento agendado"
                                                severity="warning"
                                            />
                                            <Tag
                                                v-else
                                                value="Automática"
                                                severity="success"
                                            />
                                        </div>
                                        <div v-if="plan?.description" class="mpl-info__row mpl-info__row--full">
                                            <span class="mpl-info__label">Descrição</span>
                                            <span class="mpl-info__desc">{{ plan.description }}</span>
                                        </div>
                                    </div>
                                </template>
                            </div>
                        </div>

                        <!-- Card: Resumo (mini stats) -->
                        <div v-if="subscription" class="mpl-w mpl-w--side">
                            <div class="mpl-w__head">
                                <div class="mpl-w__icon"><i class="pi pi-chart-pie" /></div>
                                <div class="mpl-w__title">
                                    <div class="mpl-w__title-text">Resumo</div>
                                    <div class="mpl-w__sub">Indicadores rápidos</div>
                                </div>
                            </div>
                            <div class="mpl-w__body">
                                <div class="mpl-stats">
                                    <div class="mpl-stat">
                                        <div class="mpl-stat__val">{{ features.length }}</div>
                                        <div class="mpl-stat__lbl">Recursos</div>
                                    </div>
                                    <div class="mpl-stat">
                                        <div class="mpl-stat__val">{{ events.length }}</div>
                                        <div class="mpl-stat__lbl">Eventos</div>
                                    </div>
                                    <div class="mpl-stat">
                                        <div class="mpl-stat__val mpl-stat__val--small">{{ renewLabel }}</div>
                                        <div class="mpl-stat__lbl">{{ subscription.cancel_at_period_end ? 'Encerra' : 'Renova' }}</div>
                                    </div>
                                </div>
                                <div class="mpl-id-row">
                                    <span class="mpl-id-row__label">ID da assinatura</span>
                                    <code class="mpl-id-row__code">{{ subscription.id }}</code>
                                </div>
                            </div>
                        </div>
                    </div>

                    <div v-if="!cfgOpen" class="mpl-side__footer">
                        <button class="mpl-btn mpl-btn--primary mpl-btn--full" @click="goUpgrade">
                            <i class="pi pi-arrow-up-right" />
                            <span>{{ subscription ? 'Alterar plano' : 'Ver planos' }}</span>
                        </button>
                    </div>
                </aside>
            </Teleport>

            <!-- ═══ COL 2: Main ═══ -->
            <div class="mpl-main">
                <!-- Empty state -->
                <div v-if="!loading && !subscription" class="mpl-w">
                    <div class="mpl-w__head">
                        <div class="mpl-w__icon"><i class="pi pi-info-circle" /></div>
                        <div class="mpl-w__title">
                            <div class="mpl-w__title-text">Sem assinatura ativa</div>
                            <div class="mpl-w__sub">Você ainda não tem um plano contratado</div>
                        </div>
                    </div>
                    <div class="mpl-w__body">
                        <div class="mpl-empty mpl-empty--big">
                            <i class="pi pi-credit-card mpl-empty__icon" />
                            <div class="mpl-empty__title">Escolha um plano pra começar</div>
                            <div class="mpl-empty__hint">
                                Ative todos os recursos do Agência PSI.
                            </div>
                            <button class="mpl-btn mpl-btn--primary" @click="goUpgrade">
                                <i class="pi pi-arrow-up-right" />
                                <span>Ver planos</span>
                            </button>
                        </div>
                    </div>
                </div>

                <!-- Loading skeleton -->
                <template v-if="loading && !hasLoaded">
                    <div class="mpl-w" v-for="n in 2" :key="`sk-${n}`">
                        <div class="mpl-w__body">
                            <Skeleton width="40%" height="20px" class="mb-3" />
                            <Skeleton v-for="m in 4" :key="`sk-${n}-${m}`" width="100%" height="32px" class="mb-2" />
                        </div>
                    </div>
                </template>

                <template v-else-if="subscription">
                    <!-- ── Recursos do plano ── -->
                    <div class="mpl-w">
                        <div class="mpl-w__head">
                            <div class="mpl-w__icon"><i class="pi pi-check-circle" /></div>
                            <div class="mpl-w__title">
                                <div class="mpl-w__title-text">Seu plano inclui</div>
                                <div class="mpl-w__sub">Recursos liberados pelo plano contratado</div>
                            </div>
                            <span v-if="features.length" class="mpl-w__count">{{ features.length }}</span>
                        </div>
                        <div class="mpl-w__body">
                            <div v-if="!features.length" class="mpl-empty mpl-empty--small">
                                <i class="pi pi-info-circle" />
                                Nenhum recurso vinculado.
                            </div>

                            <div v-else class="mpl-features">
                                <div
                                    v-for="g in groupedFeatures"
                                    :key="g.module"
                                    class="mpl-feat-group"
                                >
                                    <div class="mpl-feat-group__head">
                                        <span class="mpl-feat-group__label">{{ moduleLabel(g.module) }}</span>
                                        <div class="mpl-feat-group__line" />
                                        <span class="mpl-feat-group__count">{{ g.items.length }}</span>
                                    </div>
                                    <div class="mpl-feat-list">
                                        <div
                                            v-for="f in g.items"
                                            :key="f.key"
                                            class="mpl-feat"
                                            :title="f.description || f.key"
                                        >
                                            <i class="pi pi-check-circle mpl-feat__check" />
                                            <div class="mpl-feat__text">
                                                <div class="mpl-feat__key">{{ f.key }}</div>
                                                <div v-if="f.description" class="mpl-feat__desc">
                                                    {{ f.description }}
                                                </div>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <!-- ── Historico ── -->
                    <div class="mpl-w">
                        <div class="mpl-w__head">
                            <div class="mpl-w__icon"><i class="pi pi-history" /></div>
                            <div class="mpl-w__title">
                                <div class="mpl-w__title-text">Histórico</div>
                                <div class="mpl-w__sub">Mudanças, cancelamentos e reativações</div>
                            </div>
                            <span v-if="events.length" class="mpl-w__count">{{ events.length }}</span>
                        </div>
                        <div class="mpl-w__body">
                            <div v-if="!events.length" class="mpl-empty mpl-empty--small">
                                <i class="pi pi-history" />
                                Sem eventos registrados.
                            </div>

                            <div v-else class="mpl-events">
                                <div v-for="ev in events" :key="ev.id" class="mpl-event">
                                    <div class="mpl-event__head">
                                        <Tag
                                            :value="eventLabel(ev.event_type)"
                                            :severity="eventSeverity(ev.event_type)"
                                        />
                                        <span class="mpl-event__date">{{ fmtDate(ev.created_at) }}</span>
                                    </div>
                                    <div v-if="ev.old_plan_id || ev.new_plan_id" class="mpl-event__diff">
                                        <span class="mpl-event__plan">{{ planKeyOrName(ev.old_plan_id) }}</span>
                                        <i class="pi pi-arrow-right" />
                                        <span class="mpl-event__plan">{{ planKeyOrName(ev.new_plan_id) }}</span>
                                    </div>
                                    <div class="mpl-event__by">
                                        por <b>{{ displayUser(ev.created_by) }}</b>
                                    </div>
                                    <div v-if="ev.reason" class="mpl-event__reason">{{ ev.reason }}</div>
                                    <pre v-if="ev.metadata" class="mpl-event__meta">{{ prettyMeta(ev.metadata) }}</pre>
                                </div>
                                <div class="mpl-events__hint">Mostrando até 50 eventos (mais recentes).</div>
                            </div>
                        </div>
                    </div>
                </template>
            </div>
        </div>
    </section>
</template>

<style scoped>
/* ═══════ Page chrome (mesmo pattern do MelissaPerfil) ═══════ */
.mpl-page {
    position: absolute;
    inset: 6px 6px calc(var(--m-dock-h, 76px) + 6px) var(--m-config-aside-left, 6px);
    z-index: 40;
    display: flex;
    flex-direction: column;
    background: var(--m-bg-medium);
    backdrop-filter: blur(32px) saturate(160%);
    -webkit-backdrop-filter: blur(32px) saturate(160%);
    border: 1px solid var(--m-border);
    border-radius: 18px;
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4);
    overflow: hidden;
    font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
    color: var(--m-text);
    animation: mpl-page-enter 240ms cubic-bezier(0.2, 0.7, 0.3, 1);
}
@keyframes mpl-page-enter {
    from { opacity: 0; transform: scale(0.985); }
    to   { opacity: 1; transform: scale(1); }
}

.mpl-page__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 18px;
    border-bottom: 1px solid var(--m-border);
    flex-shrink: 0;
    gap: 10px;
}
.mpl-page__title {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 1rem;
    font-weight: 700;
    color: var(--m-text);
}
.mpl-page__title-icon {
    color: var(--p-primary-color);
    font-size: 1.05rem;
}
.mpl-page__actions {
    display: flex;
    align-items: center;
    gap: 6px;
}
.mpl-act-btn {
    width: 32px;
    height: 32px;
    display: grid;
    place-items: center;
    background: transparent;
    border: 1px solid var(--m-border);
    color: var(--m-text-muted);
    border-radius: 8px;
    cursor: pointer;
    transition: background-color 120ms ease, color 120ms ease;
}
.mpl-act-btn:hover {
    background: var(--m-bg-soft-hover);
    color: var(--m-text);
}
.mpl-act-btn:disabled { opacity: 0.45; cursor: not-allowed; }
.mpl-close {
    width: 32px;
    height: 32px;
    display: grid;
    place-items: center;
    background: transparent;
    border: 1px solid var(--m-border);
    color: var(--m-text-muted);
    border-radius: 8px;
    cursor: pointer;
    transition: background-color 120ms ease, color 120ms ease;
}
.mpl-close:hover {
    background: var(--m-bg-soft-hover);
    color: var(--m-text);
}
.mpl-menu-btn {
    display: none;
    align-items: center;
    gap: 6px;
    padding: 7px 12px;
    border-radius: 8px;
    border: 1px solid var(--m-border);
    background: var(--m-bg-soft);
    color: var(--m-text);
    cursor: pointer;
    font-size: 0.82rem;
    font-weight: 600;
    flex-shrink: 0;
}
.mpl-menu-btn:hover { background: var(--m-bg-soft-hover); }

.mpl-subheader {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 10px 18px;
    background: var(--m-bg-soft);
    border-bottom: 1px solid var(--m-border);
    color: var(--m-text-muted);
    font-size: 0.78rem;
    flex-shrink: 0;
}
.mpl-subheader__icon {
    color: var(--p-primary-color);
    font-size: 0.85rem;
    margin-top: 2px;
    flex-shrink: 0;
}

/* ═══════ Body 2-col ═══════ */
.mpl-body {
    flex: 1;
    min-height: 0;
    display: flex;
    overflow: hidden;
}
.mpl-side {
    width: 320px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    background: var(--m-bg-soft);
    border-right: 1px solid var(--m-border);
    overflow: hidden;
}
.mpl-side__scroll {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    scrollbar-width: thin;
    scrollbar-color: var(--m-border-strong) transparent;
}
.mpl-side__scroll::-webkit-scrollbar { width: 5px; }
.mpl-side__scroll::-webkit-scrollbar-thumb {
    background: var(--m-border-strong);
    border-radius: 3px;
}
.mpl-side__footer {
    flex-shrink: 0;
    padding: 12px;
    background: var(--m-bg-medium);
    border-top: 1px solid var(--m-border);
}

/* Botao "Configuracoes" no topo da .mpl-side. Click alterna entre
   cards (default) e lista de configs (estado is-open: vira "Voltar"). */
.mpl-cfg-btn {
    display: flex;
    align-items: center;
    gap: 8px;
    width: calc(100% - 24px);
    margin: 12px 12px 0;
    padding: 10px 12px;
    background: var(--m-bg-medium);
    border: 1px solid var(--m-border);
    border-radius: 9px;
    color: var(--m-text);
    cursor: pointer;
    font-family: inherit;
    font-size: 0.84rem;
    font-weight: 600;
    text-align: left;
    transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
    flex-shrink: 0;
}
.mpl-cfg-btn:hover {
    background: var(--m-bg-soft-hover);
    border-color: var(--m-border-strong);
}
.mpl-cfg-btn.is-open {
    background: color-mix(in srgb, var(--p-primary-color) 14%, transparent);
    border-color: color-mix(in srgb, var(--p-primary-color) 38%, transparent);
    color: var(--p-primary-color);
}
.mpl-cfg-btn > i:first-child {
    color: var(--p-primary-color);
    font-size: 0.92rem;
}
.mpl-cfg-btn > span { flex: 1; }
.mpl-cfg-btn__chev {
    color: var(--m-text-muted);
    font-size: 0.7rem;
}
.mpl-side__scroll--cfg {
    padding: 8px;
    gap: 0;
}

.mpl-main {
    flex: 1;
    min-width: 0;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    scrollbar-width: thin;
    scrollbar-color: var(--m-border-strong) transparent;
}
.mpl-main::-webkit-scrollbar { width: 5px; }
.mpl-main::-webkit-scrollbar-thumb {
    background: var(--m-border-strong);
    border-radius: 3px;
}

/* Desktop (>=1024): main em grid 2-col, cards min-h 300 + max-h 100%
   + body com overflow-y: auto. Sidebar (Plano atual + Resumo) ganha
   o mesmo cap pra nao crescer demais quando tem features/eventos longos. */
@media (min-width: 1024px) {
    /* Fake dialog: largura adaptativa, alinhada a esquerda (apos o
       config-aside global). Espelha pattern de Seguranca/Pagamento/etc:
       - 1024–1012px : full-width (right: 6px) — overlap minimo
       - 1012–2012px : width = 1000px fixo (right cresce com viewport)
       - >= 2012px   : width = ~50% do viewport (right: 50%) */
    .mpl-page {
        right: max(6px, min(50%, calc(100% - 1006px)));
    }

    /* Cards do main empilhados em 1-col (era grid 2-col antes).
       .mpl-main herda flex-direction: column do base — cards crescem
       com conteudo, sem scroll interno. Espelha pattern de MelissaPerfil. */
    .mpl-main > .mpl-w {
        flex-shrink: 0;
        height: auto;
    }
    /* Cards da sidebar (Plano atual + Resumo): altura natural,
       flex-shrink: 0 evita compressao quando total passa do
       .mpl-side__scroll (scroll externo). */
    .mpl-side > .mpl-side__scroll > .mpl-w--side {
        display: flex;
        flex-direction: column;
        flex-shrink: 0;
        height: auto;
    }
}

/* ═══════ Card-base (estilo MelissaFinanceiro/MelissaPerfil) ═══════ */
.mpl-w {
    background: var(--m-bg-soft);
    border: 1px solid var(--m-border);
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
    display: flex;
    flex-direction: column;
}
.mpl-w--side {
    background: var(--m-bg-medium);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.16);
}
.mpl-w__head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--m-border);
}
.mpl-w__icon {
    width: 36px;
    height: 36px;
    display: grid;
    place-items: center;
    border-radius: 9px;
    flex-shrink: 0;
    background: color-mix(in srgb, var(--p-primary-color) 15%, transparent);
    color: var(--p-primary-color);
}
.mpl-w__icon > i { font-size: 0.95rem; }
.mpl-w__title {
    flex: 1;
    min-width: 0;
}
.mpl-w__title-text {
    font-size: 0.92rem;
    font-weight: 700;
    color: var(--m-text);
    line-height: 1.2;
}
.mpl-w__sub {
    font-size: 0.74rem;
    color: var(--m-text-muted);
    margin-top: 2px;
    line-height: 1.3;
}
.mpl-w__count {
    flex-shrink: 0;
    background: color-mix(in srgb, var(--p-primary-color) 18%, transparent);
    color: var(--p-primary-color);
    border-radius: 999px;
    padding: 3px 10px;
    font-size: 0.74rem;
    font-weight: 700;
}
.mpl-w__body {
    padding: 14px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* ═══════ Buttons ═══════ */
.mpl-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 8px 14px;
    border-radius: 8px;
    border: 1px solid var(--m-border);
    background: var(--m-bg-soft);
    color: var(--m-text);
    cursor: pointer;
    font-size: 0.82rem;
    font-weight: 600;
    font-family: inherit;
    transition: background-color 120ms ease;
}
.mpl-btn:hover { background: var(--m-bg-soft-hover); }
.mpl-btn--primary {
    background: var(--p-primary-color);
    border-color: var(--p-primary-color);
    color: var(--p-primary-contrast-color, #fff);
}
.mpl-btn--primary:hover {
    background: color-mix(in srgb, var(--p-primary-color) 88%, black);
}
.mpl-btn--full { width: 100%; }

/* ═══════ Sidebar: Plano atual ═══════ */
.mpl-plan {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 12px;
    border-radius: 9px;
    background: color-mix(in srgb, var(--p-primary-color) 8%, transparent);
    border: 1px solid color-mix(in srgb, var(--p-primary-color) 25%, transparent);
}
.mpl-plan__name {
    font-size: 1.1rem;
    font-weight: 800;
    color: var(--p-primary-color);
    line-height: 1.1;
}
.mpl-plan__price {
    font-size: 0.78rem;
    color: var(--m-text);
    font-weight: 600;
}

.mpl-info {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.mpl-info__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}
.mpl-info__row--full {
    flex-direction: column;
    align-items: flex-start;
    gap: 3px;
}
.mpl-info__label {
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--m-text-muted);
    flex-shrink: 0;
}
.mpl-info__value {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--m-text);
    text-align: right;
    word-break: break-word;
}
.mpl-info__desc {
    font-size: 0.78rem;
    color: var(--m-text);
    line-height: 1.4;
}

/* ═══════ Sidebar: Resumo (mini stats) ═══════ */
.mpl-stats {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
}
.mpl-stat {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: 10px 6px;
    border-radius: 9px;
    background: var(--m-bg-soft);
    border: 1px solid var(--m-border);
    text-align: center;
}
.mpl-stat__val {
    font-size: 1.1rem;
    font-weight: 800;
    color: var(--m-text);
    line-height: 1.1;
}
.mpl-stat__val--small {
    font-size: 0.8rem;
}
.mpl-stat__lbl {
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--m-text-muted);
}

.mpl-id-row {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding-top: 4px;
    border-top: 1px solid var(--m-border);
}
.mpl-id-row__label {
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--m-text-muted);
}
.mpl-id-row__code {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.7rem;
    color: var(--m-text-muted);
    word-break: break-all;
    user-select: all;
}

/* ═══════ Empty states ═══════ */
.mpl-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 16px 8px;
    text-align: center;
}
.mpl-empty--small {
    flex-direction: row;
    padding: 12px;
    color: var(--m-text-muted);
    font-size: 0.85rem;
}
.mpl-empty--small > i { color: var(--p-primary-color); }
.mpl-empty--big {
    padding: 36px 24px;
    gap: 10px;
}
.mpl-empty__icon {
    font-size: 2rem;
    color: var(--m-text-faint);
    opacity: 0.6;
}
.mpl-empty--big .mpl-empty__icon { font-size: 2.5rem; }
.mpl-empty__title {
    font-size: 0.92rem;
    font-weight: 700;
    color: var(--m-text);
}
.mpl-empty__hint {
    font-size: 0.78rem;
    color: var(--m-text-muted);
    line-height: 1.4;
}

/* ═══════ Recursos do plano (features grouped) ═══════ */
.mpl-features {
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.mpl-feat-group__head {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 6px;
}
.mpl-feat-group__label {
    font-size: 0.66rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--p-primary-color);
}
.mpl-feat-group__line {
    flex: 1;
    height: 1px;
    background: var(--m-border);
}
.mpl-feat-group__count {
    font-size: 0.66rem;
    font-weight: 700;
    color: var(--m-text-muted);
    background: var(--m-bg-medium);
    border: 1px solid var(--m-border);
    border-radius: 999px;
    padding: 1px 7px;
}
.mpl-feat-list {
    display: grid;
    grid-template-columns: 1fr;
    gap: 4px;
}
@media (min-width: 600px) {
    .mpl-feat-list { grid-template-columns: 1fr 1fr; }
}
.mpl-feat {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 6px 8px;
    border-radius: 6px;
    transition: background-color 120ms ease;
}
.mpl-feat:hover { background: var(--m-bg-medium); }
.mpl-feat__check {
    color: rgb(22, 163, 74);
    font-size: 0.85rem;
    margin-top: 2px;
    flex-shrink: 0;
}
.mpl-feat__text { min-width: 0; flex: 1; }
.mpl-feat__key {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--m-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mpl-feat__desc {
    font-size: 0.7rem;
    color: var(--m-text-muted);
    line-height: 1.3;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ═══════ Historico (events) ═══════ */
.mpl-events {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.mpl-event {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 10px 12px;
    border-radius: 9px;
    background: var(--m-bg-medium);
    border: 1px solid var(--m-border);
}
.mpl-event__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    flex-wrap: wrap;
}
.mpl-event__date {
    font-size: 0.7rem;
    color: var(--m-text-muted);
}
.mpl-event__diff {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.78rem;
    color: var(--m-text-muted);
    flex-wrap: wrap;
}
.mpl-event__diff > i { font-size: 0.68rem; opacity: 0.6; }
.mpl-event__plan {
    color: var(--m-text);
    font-weight: 600;
}
.mpl-event__by {
    font-size: 0.74rem;
    color: var(--m-text-muted);
}
.mpl-event__by > b { color: var(--m-text); font-weight: 600; }
.mpl-event__reason {
    font-size: 0.74rem;
    color: var(--m-text-muted);
    font-style: italic;
}
.mpl-event__meta {
    margin: 4px 0 0;
    padding: 6px 8px;
    border-radius: 6px;
    background: var(--m-bg-soft);
    font-size: 0.68rem;
    color: var(--m-text-muted);
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    white-space: pre-wrap;
    word-break: break-word;
    max-height: 120px;
    overflow-y: auto;
}
.mpl-events__hint {
    font-size: 0.7rem;
    color: var(--m-text-muted);
    text-align: center;
    padding-top: 4px;
}

/* ═══════ Mobile drawer ═══════ */
.mpl-mobile-drawer {
    position: fixed;
    top: 0; left: 0;
    height: 100vh;
    height: 100dvh;
    width: min(360px, 88vw);
    z-index: 80;
    background: var(--m-bg-medium);
    backdrop-filter: blur(28px) saturate(160%);
    -webkit-backdrop-filter: blur(28px) saturate(160%);
    border-right: 1px solid var(--m-border);
    transform: translateX(-100%);
    transition: transform 250ms cubic-bezier(0.4, 0, 0.2, 1);
    color: var(--m-text);
    font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
    display: flex;
    flex-direction: column;
}
.mpl-mobile-drawer.is-open { transform: translateX(0); }
.mpl-mobile-drawer__scroll {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    scrollbar-width: thin;
    scrollbar-color: var(--m-border-strong) transparent;
}
.mpl-mobile-drawer__scroll::-webkit-scrollbar { width: 5px; }
.mpl-mobile-drawer__scroll::-webkit-scrollbar-thumb {
    background: var(--m-border-strong);
    border-radius: 3px;
}
/* No mobile a .mpl-side e teleportada pra dentro do drawer scroll.
   Reset pra ela ocupar largura total e sem border-right. */
.mpl-mobile-drawer__scroll .mpl-side {
    width: 100%;
    border-right: none;
}

.mpl-mobile-drawer__backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    z-index: 79;
}
.mpl-drawer-fade-enter-active,
.mpl-drawer-fade-leave-active { transition: opacity 200ms ease; }
.mpl-drawer-fade-enter-from,
.mpl-drawer-fade-leave-to { opacity: 0; }

/* ═══════ Mobile (<1024px) ═══════ */
@media (max-width: 1023px) {
    .mpl-body {
        flex-direction: column;
        padding: 0;
    }
    /* No mobile a .mpl-side e teleportada pro drawer; oculta a copia
       inline (caso a teleport target nao monte por algum motivo). */
    .mpl-body > .mpl-side { display: none; }
    .mpl-main {
        width: 100%;
        padding: 8px;
    }
    .mpl-main .mpl-w {
        height: auto;
        flex: 0 0 auto;
        align-self: stretch;
    }
    .mpl-page__title > span:first-of-type { display: none; }
    .mpl-page__title-icon { display: none; }
    .mpl-menu-btn--mobile-only { display: inline-flex; }
}
</style>
