<!--
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/features/financeiro/pages/FinanceiroDashboardPage.vue
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
-->

<script setup>
import { ref, computed, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import { supabase } from '@/lib/supabase/client';

import { tenantDb } from '@/lib/supabase/tenantClient';
import { useTenantStore } from '@/stores/tenantStore';
// ─── helpers ─────────────────────────────────────────────────────────────────
const router = useRouter();
const tenantStore = useTenantStore();

const _brl = new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' });
function fmtBRL(v) {
    return _brl.format(v ?? 0);
}

function fmtDate(iso) {
    if (!iso) return '—';
    const d = iso.includes('T') ? new Date(iso) : new Date(iso + 'T00:00:00');
    return new Intl.DateTimeFormat('pt-BR').format(d);
}

async function getUid() {
    const { data } = await supabase.auth.getUser();
    return data?.user?.id ?? null;
}

// ─── meses para o gráfico ────────────────────────────────────────────────────
function getLast6Months() {
    const months = [];
    const now = new Date();
    for (let i = 5; i >= 0; i--) {
        const d = new Date(now.getFullYear(), now.getMonth() - i, 1);
        months.push({ year: d.getFullYear(), month: d.getMonth() + 1, label: d.toLocaleDateString('pt-BR', { month: 'short', year: '2-digit' }) });
    }
    return months;
}

// ─── estado: cards de resumo ─────────────────────────────────────────────────
const summaryLoading = ref(true);
const totalRecebido = ref(0);
const totalPendente = ref(0);
const totalVencido = ref(0);
const totalDespesas = ref(0);

async function loadSummary(uid) {
    summaryLoading.value = true;
    const now = new Date();
    const year = now.getFullYear();
    const month = now.getMonth() + 1;

    try {
        // Receitas e despesas pagas no mês via RPC
        const { data: rpc } = await supabase.rpc('get_financial_summary', {
            p_tenant_id: tenantStore.activeTenantId,
            p_owner_id: uid,
            p_year: year,
            p_month: month
        });
        const s = Array.isArray(rpc) ? rpc[0] : rpc;
        totalRecebido.value = Number(s?.total_receitas ?? 0);
        totalDespesas.value = Number(s?.total_despesas ?? 0);

        // Pending e overdue separados (sem filtro de mês)
        const { data: pendRows } = await tenantDb().from('financial_records').select('status, final_amount').eq('owner_id', uid).is('deleted_at', null).in('status', ['pending', 'overdue']);

        let pen = 0,
            ove = 0;
        for (const r of pendRows ?? []) {
            if (r.status === 'pending') pen += Number(r.final_amount ?? 0);
            else ove += Number(r.final_amount ?? 0);
        }
        totalPendente.value = pen;
        totalVencido.value = ove;
    } finally {
        summaryLoading.value = false;
    }
}

// ─── estado: gráfico 6 meses ─────────────────────────────────────────────────
const chartLoading = ref(true);
const chartData = ref(null);
const chartOptions = ref({
    responsive: true,
    maintainAspectRatio: false,
    plugins: {
        legend: { position: 'top' },
        tooltip: {
            callbacks: {
                label: (ctx) => ` ${_brl.format(ctx.parsed.y)}`
            }
        }
    },
    scales: {
        y: {
            ticks: { callback: (v) => _brl.format(v) },
            beginAtZero: true
        }
    }
});

async function loadChart(uid) {
    chartLoading.value = true;
    const months = getLast6Months();
    try {
        const results = await Promise.all(months.map((m) => supabase.rpc('get_financial_summary', { p_tenant_id: tenantStore.activeTenantId, p_owner_id: uid, p_year: m.year, p_month: m.month })));
        const receitas = results.map((r) => Number((Array.isArray(r.data) ? r.data[0] : r.data)?.total_receitas ?? 0));
        const despesas = results.map((r) => Number((Array.isArray(r.data) ? r.data[0] : r.data)?.total_despesas ?? 0));

        chartData.value = {
            labels: months.map((m) => m.label),
            datasets: [
                { label: 'Receita', data: receitas, backgroundColor: '#22c55e', borderRadius: 4 },
                { label: 'Despesa', data: despesas, backgroundColor: '#ef4444', borderRadius: 4 }
            ]
        };
    } finally {
        chartLoading.value = false;
    }
}

// ─── estado: fluxo de caixa ──────────────────────────────────────────────────
const cashflowLoading = ref(true);
const cashflowRows = ref([]);
const cashflowError = ref(false);

async function loadCashflow() {
    cashflowLoading.value = true;
    cashflowError.value = false;
    try {
        const { data, error } = await tenantDb().from('v_cashflow_projection').select('mes_label, receitas_projetadas, despesas_projetadas, saldo_projetado, count_registros').order('mes', { ascending: true });
        if (error) throw error;
        cashflowRows.value = data ?? [];
    } catch {
        cashflowError.value = true;
    } finally {
        cashflowLoading.value = false;
    }
}

// ─── estado: últimos lançamentos ─────────────────────────────────────────────
const recentLoading = ref(true);
const recentRecords = ref([]);

const STATUS_CFG = {
    pending: { label: 'Pendente', severity: 'warn' },
    paid: { label: 'Pago', severity: 'success' },
    overdue: { label: 'Vencido', severity: 'danger' },
    partial: { label: 'Parcial', severity: 'info' },
    cancelled: { label: 'Cancelado', severity: 'secondary' },
    refunded: { label: 'Estornado', severity: 'contrast' }
};

async function loadRecent(uid) {
    recentLoading.value = true;
    try {
        const { data } = await supabase.rpc('list_financial_records', {
            p_tenant_id: tenantStore.activeTenantId,
            p_owner_id: uid,
            p_limit: 5,
            p_offset: 0
        });
        recentRecords.value = data ?? [];
    } finally {
        recentLoading.value = false;
    }
}

// ─── navegação ───────────────────────────────────────────────────────────────
function goToLancamentos() {
    // Tenta navegar pelo nome da rota; fallback para push relativo
    const route = router.currentRoute.value;
    const base = route.matched[0]?.path ?? '';
    router.push(base + '/financeiro/lancamentos');
}

// ─── mount ───────────────────────────────────────────────────────────────────
onMounted(async () => {
    const uid = await getUid();
    if (!uid) return;
    await Promise.all([loadSummary(uid), loadChart(uid), loadCashflow(), loadRecent(uid)]);
});
</script>

<template>
    <div class="min-h-[calc(100vh-4.5rem)] bg-[var(--surface-ground,#f5f7fa)]">
        <div class="px-3 md:px-4 pt-3 pb-4 flex flex-col gap-3.5">
            <!-- ══════════════════════════════════════
         Hero
    ═══════════════════════════════════════ -->
            <section
                class="sticky mt-4 mb-4 z-20 overflow-hidden rounded-md border border-[var(--surface-border,#e2e8f0)] bg-[var(--surface-card,#fff)] p-5"
                :style="{ top: 'var(--layout-sticky-top, 56px)' }"
            >
                <!-- Blobs decorativos -->
                <div class="absolute inset-0 pointer-events-none overflow-hidden" aria-hidden="true">
                    <div class="absolute w-72 h-72 -top-16 -right-12 rounded-full blur-[70px] bg-indigo-500/10" />
                    <div class="absolute w-80 h-80 top-2 -left-20 rounded-full blur-[70px] bg-emerald-400/[0.08]" />
                </div>

                <!-- Linha 1: icon + título + botão -->
                <div class="relative z-1 flex items-center gap-3">
                    <div class="flex items-center gap-2.5 flex-1 min-w-0">
                        <div class="cfg-subheader__icon grid place-items-center w-10 h-10 rounded-md shrink-0" style="background: color-mix(in srgb, #10b981 15%, transparent); color: #059669">
                            <i class="pi pi-wallet text-lg" />
                        </div>
                        <div class="min-w-0">
                            <div class="text-[1.05rem] font-bold tracking-tight text-[var(--text-color)]">Financeiro</div>
                            <div class="text-[0.78rem] text-[var(--text-color-secondary)] mt-0.5">Resumo e visão geral do período</div>
                        </div>
                    </div>
                    <div class="flex items-center gap-2 shrink-0">
                        <Button label="Ver lançamentos" icon="pi pi-list" severity="secondary" outlined class="rounded-full hidden sm:flex" @click="goToLancamentos" />
                    </div>
                </div>

                <!-- Linha 2: quick stats -->
                <div class="relative z-1 mt-2.5">
                    <template v-if="summaryLoading">
                        <div class="grid grid-cols-2 lg:grid-cols-4 gap-2.5">
                            <div v-for="n in 4" :key="n" class="flex flex-col gap-1.5 px-4 py-2.5 rounded-md border border-[var(--surface-border)]">
                                <Skeleton width="3rem" height="20px" />
                                <Skeleton width="4.5rem" height="10px" />
                            </div>
                        </div>
                    </template>

                    <template v-else>
                        <div class="grid grid-cols-2 lg:grid-cols-4 gap-2.5">
                            <!-- Recebido -->
                            <div class="flex flex-col gap-0.5 px-4 py-2.5 rounded-md border border-emerald-500/25 bg-emerald-500/5">
                                <div class="text-[1.35rem] font-bold leading-none text-emerald-600">{{ fmtBRL(totalRecebido) }}</div>
                                <div class="flex items-center gap-1.5 text-[0.7rem] text-emerald-700/80 font-semibold">
                                    <i class="pi pi-check-circle text-xs" />
                                    Recebido (mês)
                                </div>
                            </div>

                            <!-- Pendente -->
                            <div class="flex flex-col gap-0.5 px-4 py-2.5 rounded-md border border-amber-500/25 bg-amber-500/5">
                                <div class="text-[1.35rem] font-bold leading-none text-amber-500">{{ fmtBRL(totalPendente) }}</div>
                                <div class="flex items-center gap-1.5 text-[0.7rem] text-amber-600/80 font-semibold">
                                    <span class="h-1.5 w-1.5 rounded-full bg-amber-400 animate-pulse shrink-0" />
                                    Pendente
                                </div>
                            </div>

                            <!-- Vencido -->
                            <div class="flex flex-col gap-0.5 px-4 py-2.5 rounded-md border" :class="totalVencido > 0 ? 'border-red-500/25 bg-red-500/5' : 'border-[var(--surface-border)] bg-[var(--surface-ground)]'">
                                <div class="text-[1.35rem] font-bold leading-none" :class="totalVencido > 0 ? 'text-red-500' : 'text-[var(--text-color)]'">{{ fmtBRL(totalVencido) }}</div>
                                <div class="flex items-center gap-1.5 text-[0.7rem] font-semibold" :class="totalVencido > 0 ? 'text-red-600/80' : 'text-[var(--text-color-secondary)] opacity-75'">
                                    <i class="pi pi-exclamation-circle text-xs" />
                                    Vencido
                                </div>
                            </div>

                            <!-- Despesas -->
                            <div class="flex flex-col gap-0.5 px-4 py-2.5 rounded-md border border-[var(--surface-border)] bg-[var(--surface-ground)]">
                                <div class="text-[1.35rem] font-bold leading-none text-[var(--text-color)]">{{ fmtBRL(totalDespesas) }}</div>
                                <div class="flex items-center gap-1.5 text-[0.7rem] text-[var(--text-color-secondary)] opacity-75 font-semibold">
                                    <i class="pi pi-arrow-down-left text-xs" />
                                    Despesas (mês)
                                </div>
                            </div>
                        </div>
                    </template>
                </div>
            </section>

            <!-- ══════════════════════════════════════
         Gráfico Receita × Despesa
    ═══════════════════════════════════════ -->
            <section class="dash-card rounded-md">
                <div class="dash-card__head gap-2.5 p-2.5">
                    <div class="grid place-items-center w-10 h-10 rounded-md shrink-0 bg-indigo-500/10 text-indigo-500">
                        <i class="pi pi-chart-bar text-lg" />
                    </div>
                    <div>
                        <div class="font-bold tracking-tight text-[var(--text-color-secondary)]">Receita × Despesa</div>
                        <div class="dash-card__sub">Comparativo dos últimos 6 meses</div>
                    </div>
                </div>
                <div class="px-3 pb-3 pt-2">
                    <div v-if="chartLoading" class="h-[240px]">
                        <Skeleton height="100%" />
                    </div>
                    <div v-else-if="chartData" class="h-[240px]">
                        <Chart type="bar" :data="chartData" :options="chartOptions" style="height: 100%" />
                    </div>
                    <div v-else class="flex items-center justify-center gap-2 py-10 text-[var(--text-color-secondary)]"><i class="pi pi-info-circle" /> Sem dados para o gráfico.</div>
                </div>
            </section>

            <!-- ══════════════════════════════════════
         Projeção de Caixa
    ═══════════════════════════════════════ -->
            <section class="dash-card rounded-md">
                <div class="dash-card__head gap-2.5 p-2.5">
                    <div class="grid place-items-center w-10 h-10 rounded-md shrink-0 bg-indigo-500/10 text-indigo-500">
                        <i class="pi pi-calendar text-lg" />
                    </div>
                    <div>
                        <div class="font-bold tracking-tight text-[var(--text-color-secondary)]">Projeção de Caixa</div>
                        <div class="dash-card__sub">Cobranças em aberto — próximos 6 meses</div>
                    </div>
                </div>
                <div class="px-3 pb-3 pt-1">
                    <div v-if="cashflowLoading" class="flex flex-col gap-2 pt-1">
                        <Skeleton v-for="n in 6" :key="n" height="2.4rem" border-radius="6px" />
                    </div>

                    <div v-else-if="cashflowError" class="flex items-center justify-center gap-2 py-8 text-[var(--text-color-secondary)]"><i class="pi pi-info-circle" /> Projeção indisponível.</div>

                    <div v-else-if="!cashflowRows.length" class="flex items-center justify-center gap-2 py-8 text-[var(--text-color-secondary)]"><i class="pi pi-check-circle" /> Sem cobranças futuras em aberto.</div>

                    <div v-else class="flex flex-col gap-1.5 pt-1">
                        <div v-for="row in cashflowRows" :key="row.mes_label" class="flex items-center gap-3 px-3 py-2.5 rounded-md bg-[var(--surface-ground,#f8fafc)] hover:bg-[var(--surface-hover,#f1f5f9)] transition-colors duration-100">
                            <span class="font-bold text-[0.8rem] uppercase tracking-wide text-[var(--text-color)] min-w-[3.5rem] shrink-0">{{ row.mes_label }}</span>
                            <div class="flex items-center gap-2 flex-1 flex-wrap text-[0.8rem]">
                                <span class="flex items-center gap-1 text-emerald-600 font-semibold">
                                    <i class="pi pi-arrow-up-right text-xs" />
                                    {{ fmtBRL(row.receitas_projetadas) }}
                                </span>
                                <span class="text-[var(--text-color-secondary)] opacity-30">·</span>
                                <span class="flex items-center gap-1 text-red-500 font-semibold">
                                    <i class="pi pi-arrow-down-left text-xs" />
                                    {{ fmtBRL(row.despesas_projetadas) }}
                                </span>
                                <span class="text-[var(--text-color-secondary)] opacity-30">·</span>
                                <span class="font-bold" :class="Number(row.saldo_projetado) >= 0 ? 'text-emerald-600' : 'text-red-500'"> saldo {{ fmtBRL(row.saldo_projetado) }} </span>
                            </div>
                            <Tag :value="row.count_registros + ' cobranças'" severity="secondary" class="ml-auto text-xs shrink-0" />
                        </div>
                    </div>
                </div>
            </section>

            <!-- ══════════════════════════════════════
         Últimos lançamentos
    ═══════════════════════════════════════ -->
            <section class="dash-card rounded-md shadow-[0_0_0_3px_color-mix(in_srgb,var(--primary-color)_7%,transparent)]">
                <div class="dash-card__head gap-2.5 p-2.5">
                    <div class="grid place-items-center w-10 h-10 rounded-md shrink-0 bg-indigo-500/10 text-indigo-500">
                        <i class="pi pi-list text-lg" />
                    </div>
                    <div class="flex-1">
                        <div class="font-bold tracking-tight text-[var(--text-color-secondary)]">Últimos lançamentos</div>
                        <div class="dash-card__sub">Cobranças e receitas recentes</div>
                    </div>
                    <button class="flex items-center gap-1 bg-transparent border-none cursor-pointer text-xs font-semibold text-[var(--primary-color,#6366f1)] p-0 shrink-0" @click="goToLancamentos">
                        Ver todos <i class="pi pi-arrow-right text-xs" />
                    </button>
                </div>

                <div v-if="recentLoading" class="px-3 pb-3 pt-1 flex flex-col gap-2">
                    <Skeleton v-for="n in 5" :key="n" height="2.5rem" border-radius="6px" />
                </div>

                <div v-else-if="!recentRecords.length" class="flex items-center justify-center gap-2 py-10 text-[var(--text-color-secondary)]"><i class="pi pi-wallet opacity-40" /> Nenhum lançamento encontrado.</div>

                <DataTable v-else :value="recentRecords" size="small" :show-gridlines="false" class="recent-table">
                    <Column field="due_date" header="Data">
                        <template #body="{ data }">
                            {{ fmtDate(data.paid_at ?? data.due_date) }}
                        </template>
                    </Column>

                    <Column field="description" header="Descrição">
                        <template #body="{ data }">
                            {{ data.description || data.notes || '—' }}
                        </template>
                    </Column>

                    <Column header="Tipo">
                        <template #body="{ data }">
                            <Tag :value="data.type === 'receita' ? 'Receita' : 'Despesa'" :severity="data.type === 'receita' ? 'success' : 'danger'" class="text-xs" />
                        </template>
                    </Column>

                    <Column header="Valor">
                        <template #body="{ data }">
                            <span :class="data.type === 'receita' ? 'text-emerald-600 font-semibold' : 'text-red-500 font-semibold'">
                                {{ fmtBRL(data.final_amount ?? data.amount) }}
                            </span>
                        </template>
                    </Column>

                    <Column header="Status">
                        <template #body="{ data }">
                            <Tag :value="STATUS_CFG[data.status]?.label ?? data.status" :severity="STATUS_CFG[data.status]?.severity ?? 'secondary'" :class="data.status === 'refunded' ? 'tag-refunded' : ''" class="text-xs" />
                        </template>
                    </Column>
                </DataTable>
            </section>
        </div>
    </div>
</template>

<style scoped>
/* ── recent table ───────────────────────────────────────────── */
.recent-table :deep(.p-datatable-thead > tr > th) {
    background: var(--surface-ground);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 0.5rem 0.75rem;
}
.recent-table :deep(.p-datatable-tbody > tr > td) {
    padding: 0.55rem 0.75rem;
    font-size: 0.85rem;
}

/* ── tag: refunded (roxo) ───────────────────────────────────── */
:deep(.tag-refunded) {
    background: #a855f7 !important;
    color: #fff !important;
}
</style>
