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

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

// "Voltar" preserva o layout (Melissa vs /configuracoes).
const inMelissa = computed(() => String(route.path || '').startsWith('/melissa'));
function goBack() {
    router.push(inMelissa.value ? '/melissa/cfg-recursos-extras' : '/configuracoes/recursos-extras');
}

const { rows, balances, filters, dateRange, loading, summary, load, loadBalances } = useAddonExtrato();

const tenantName = ref('');
const exportingPdf = ref(false);

// ── opções dos filtros ──────────────────────────────────────────────────

const periodOptions = [
    { label: 'Este mês', value: 'thisMonth' },
    { label: 'Mês anterior', value: 'lastMonth' },
    { label: 'Últimos 90 dias', value: 'last90' },
    { label: 'Personalizado', value: 'custom' }
];

const addonTypeOptions = [
    { label: 'SMS', value: 'sms' },
    { label: 'E-mail', value: 'email' },
    { label: 'Servidor', value: 'server' },
    { label: 'Domínio', value: 'domain' }
];

const movementOptions = [
    { label: 'Compra', value: 'purchase' },
    { label: 'Consumo', value: 'consumption' },
    { label: 'Ajuste', value: 'adjustment' },
    { label: 'Reembolso', value: 'refund' },
    { label: 'Bônus', value: 'bonus' },
    { label: 'Expiração', value: 'expiration' }
];

// ── labels ──────────────────────────────────────────────────────────────

const periodLabel = computed(() => {
    const preset = periodOptions.find((p) => p.value === filters.value.periodPreset)?.label ?? '';
    const { from, to } = dateRange.value;
    const fmt = (d) => new Date(d).toLocaleDateString('pt-BR');
    return `${preset} (${fmt(from)} → ${fmt(to)})`;
});

function movementSeverity(type) {
    const map = { purchase: 'success', consumption: 'warning', adjustment: 'info', refund: 'secondary', bonus: 'success', expiration: 'danger' };
    return map[type] || 'secondary';
}

function amountClass(r) {
    if (r.type === 'consumption' || r.type === 'expiration') return 'text-red-500 font-semibold';
    if (r.type === 'purchase' || r.type === 'bonus' || r.type === 'refund') return 'text-emerald-500 font-semibold';
    return '';
}

// ── ações ───────────────────────────────────────────────────────────────

async function reload() {
    await Promise.all([load(), loadBalances()]);
}

function onFilterChange() {
    // recarrega apenas quando muda filtro server-side (período/addon/movimento)
    reload();
}

function slugify(s) {
    if (!s) return 'clinica';
    return String(s)
        .toLowerCase()
        .normalize('NFD')
        .replace(/[\u0300-\u036f]/g, '')
        .replace(/[^a-z0-9]+/g, '-')
        .replace(/(^-|-$)/g, '')
        .slice(0, 40) || 'clinica';
}

function filenameBase() {
    const now = new Date();
    const ym = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`;
    return `extrato-addons-${slugify(tenantName.value)}-${ym}`;
}

function onExportCSV() {
    try {
        downloadExtratoCSV(rows.value, summary.value, periodLabel.value, `${filenameBase()}.csv`);
        toast.add({ severity: 'success', summary: 'CSV gerado', detail: `${summary.value.totalRows} registro(s) exportado(s).`, life: 3000 });
    } catch (err) {
        toast.add({ severity: 'error', summary: 'Falha ao gerar CSV', detail: err?.message || 'Erro inesperado', life: 5000 });
    }
}

async function onExportPDF() {
    if (exportingPdf.value) return;
    exportingPdf.value = true;
    try {
        await downloadExtratoPDF(rows.value, summary.value, periodLabel.value, tenantName.value, `${filenameBase()}.pdf`);
        toast.add({ severity: 'success', summary: 'PDF gerado', detail: `${summary.value.totalRows} registro(s) exportado(s).`, life: 3000 });
    } catch (err) {
        toast.add({ severity: 'error', summary: 'Falha ao gerar PDF', detail: err?.message || 'Erro inesperado', life: 5000 });
    } finally {
        exportingPdf.value = false;
    }
}

async function onExportExcel() {
    try {
        await downloadExcel({
            filename: `${filenameBase()}.xlsx`,
            sheetName: 'Extrato de addons',
            headers: [
                { key: 'created_at', label: 'Data/Hora', type: 'date', width: 20 },
                { key: 'addon_label', label: 'Recurso', type: 'text', width: 14 },
                { key: 'movement_label', label: 'Tipo', type: 'text', width: 14 },
                { key: 'amount', label: 'Quantidade', type: 'number', width: 14 },
                { key: 'balance_after', label: 'Saldo após', type: 'number', width: 14 },
                { key: 'description', label: 'Descrição', type: 'text', width: 40 },
                { key: 'price_cents', label: 'Valor', type: 'money', width: 14 },
                { key: 'payment_method', label: 'Método', type: 'text', width: 14 },
                { key: 'payment_reference', label: 'Referência', type: 'text', width: 28 }
            ],
            rows: rows.value.map((r) => ({
                ...r,
                addon_label: formatters.addonLabel(r.addon_type),
                movement_label: formatters.movementLabel(r.type)
            })),
            footerRows: [
                ['Período', periodLabel.value],
                ['Total de registros', summary.value.totalRows],
                ['Total comprado (créditos)', summary.value.purchasedCredits],
                ['Total comprado (R$)', summary.value.purchasedCents / 100],
                ['Total consumido (créditos)', summary.value.consumedCredits]
            ]
        });
        toast.add({ severity: 'success', summary: 'Excel gerado', detail: `${summary.value.totalRows} registro(s) exportado(s).`, life: 3000 });
    } catch (err) {
        toast.add({ severity: 'error', summary: 'Falha ao gerar Excel', detail: err?.message || 'Erro inesperado', life: 5000 });
    }
}

async function loadTenantName() {
    const tenantId = tenantStore.activeTenantId;
    if (!tenantId) return;
    const { data } = await supabase.from('tenants').select('name').eq('id', tenantId).maybeSingle();
    tenantName.value = data?.name || '';
}

// ── init ────────────────────────────────────────────────────────────────

onMounted(async () => {
    await loadTenantName();
    await reload();
});

// recarrega quando muda tenant ativo
watch(
    () => tenantStore.activeTenantId,
    async () => {
        await loadTenantName();
        await reload();
    }
);
</script>

<template>
    <div class="flex flex-col gap-5">
        <!-- Header -->
        <Card>
            <template #title>
                <div class="flex items-center gap-2">
                    <Button icon="pi pi-arrow-left" text rounded severity="secondary" class="!w-8 !h-8" @click="goBack" v-tooltip.bottom="'Voltar'" />
                    <i class="pi pi-list text-xl" />
                    Extrato de Recursos Extras
                </div>
            </template>
            <template #subtitle> Histórico de compras, consumos e ajustes. Use para disputar cobranças ou planejar renovações. </template>
        </Card>

        <!-- Filtros -->
        <Card>
            <template #content>
                <div class="grid grid-cols-1 md:grid-cols-12 gap-3">
                    <div :class="inMelissa ? 'md:col-span-6' : 'md:col-span-3'">
                        <label class="text-xs font-medium text-surface-500 mb-1 block">Período</label>
                        <Select v-model="filters.periodPreset" :options="periodOptions" optionLabel="label" optionValue="value" class="w-full" @change="onFilterChange" />
                    </div>

                    <div v-if="filters.periodPreset === 'custom'" :class="inMelissa ? 'md:col-span-6' : 'md:col-span-4'">
                        <label class="text-xs font-medium text-surface-500 mb-1 block">Intervalo personalizado</label>
                        <DatePicker v-model="filters.customRange" selectionMode="range" dateFormat="dd/mm/yy" :manualInput="false" showIcon class="w-full" @update:model-value="onFilterChange" />
                    </div>

                    <div :class="inMelissa ? 'md:col-span-6' : 'md:col-span-3'">
                        <label class="text-xs font-medium text-surface-500 mb-1 block">Tipo de recurso</label>
                        <MultiSelect v-model="filters.addonTypes" :options="addonTypeOptions" optionLabel="label" optionValue="value" placeholder="Todos" class="w-full" display="chip" :maxSelectedLabels="2" @change="onFilterChange" />
                    </div>

                    <div :class="inMelissa ? 'md:col-span-6' : 'md:col-span-3'">
                        <label class="text-xs font-medium text-surface-500 mb-1 block">Tipo de movimento</label>
                        <MultiSelect v-model="filters.movementTypes" :options="movementOptions" optionLabel="label" optionValue="value" placeholder="Todos" class="w-full" display="chip" :maxSelectedLabels="2" @change="onFilterChange" />
                    </div>

                    <div :class="inMelissa ? 'md:col-span-6' : 'md:col-span-12'">
                        <label class="text-xs font-medium text-surface-500 mb-1 block">Buscar por referência / descrição / método</label>
                        <IconField>
                            <InputIcon class="pi pi-search" />
                            <InputText v-model="filters.search" placeholder="ex: ID de pagamento, descrição..." class="w-full" maxlength="120" />
                        </IconField>
                    </div>

                    <div class="md:col-span-12 flex items-end gap-2 flex-wrap md:flex-nowrap">
                        <Button class="md:flex-1" label="Atualizar" icon="pi pi-refresh" severity="secondary" outlined @click="reload" :loading="loading" />
                        <Button class="md:flex-1" label="Exportar CSV" icon="pi pi-file" severity="secondary" @click="onExportCSV" :disabled="!rows.length" />
                        <Button class="md:flex-1" label="Exportar Excel" icon="pi pi-file-excel" severity="secondary" @click="onExportExcel" :disabled="!rows.length" />
                        <Button class="md:flex-1" label="Exportar PDF" icon="pi pi-file-pdf" severity="secondary" @click="onExportPDF" :disabled="!rows.length" :loading="exportingPdf" />
                    </div>
                </div>
            </template>
        </Card>

        <!-- Resumo: em /melissa teleporta pro drawer (#cfg-page-side) empilhado em
             1 coluna; em /configuracoes fica inline em 4 colunas (md+). -->
        <Teleport to="#cfg-page-side" :disabled="!inMelissa" defer>
        <div :class="inMelissa ? 'flex flex-col gap-3' : 'grid grid-cols-2 md:grid-cols-4 gap-3'">
            <Card>
                <template #content>
                    <div class="flex flex-col">
                        <span class="text-xs text-surface-500 uppercase tracking-wide">Registros no período</span>
                        <span class="text-2xl font-bold mt-1">{{ summary.totalRows }}</span>
                    </div>
                </template>
            </Card>
            <Card>
                <template #content>
                    <div class="flex flex-col">
                        <span class="text-xs text-surface-500 uppercase tracking-wide">Comprado (créditos)</span>
                        <span class="text-2xl font-bold mt-1 text-emerald-500">+{{ summary.purchasedCredits }}</span>
                    </div>
                </template>
            </Card>
            <Card>
                <template #content>
                    <div class="flex flex-col">
                        <span class="text-xs text-surface-500 uppercase tracking-wide">Comprado (R$)</span>
                        <span class="text-2xl font-bold mt-1">{{ formatters.fmtBRL(summary.purchasedCents) || 'R$ 0,00' }}</span>
                    </div>
                </template>
            </Card>
            <Card>
                <template #content>
                    <div class="flex flex-col">
                        <span class="text-xs text-surface-500 uppercase tracking-wide">Consumido (créditos)</span>
                        <span class="text-2xl font-bold mt-1 text-red-500">-{{ summary.consumedCredits }}</span>
                    </div>
                </template>
            </Card>
        </div>
        </Teleport>

        <!-- Tabela -->
        <Card>
            <template #content>
                <DataTable
                    :value="rows"
                    :loading="loading"
                    size="small"
                    stripedRows
                    paginator
                    :rows="20"
                    :rowsPerPageOptions="[10, 20, 50, 100]"
                    sortField="created_at"
                    :sortOrder="-1"
                    emptyMessage="Nenhuma transação encontrada no período. Ajuste os filtros ou selecione um intervalo mais amplo."
                    scrollable
                >
                    <Column field="created_at" header="Data" style="min-width: 150px" sortable>
                        <template #body="{ data }">{{ formatters.fmtDate(data.created_at) }}</template>
                    </Column>

                    <Column field="addon_type" header="Recurso" style="width: 110px" sortable>
                        <template #body="{ data }">
                            <Tag :value="formatters.addonLabel(data.addon_type)" severity="info" />
                        </template>
                    </Column>

                    <Column field="type" header="Tipo" style="width: 130px" sortable>
                        <template #body="{ data }">
                            <Tag :value="formatters.movementLabel(data.type)" :severity="movementSeverity(data.type)" />
                        </template>
                    </Column>

                    <Column field="amount" header="Qtd." style="width: 90px" sortable>
                        <template #body="{ data }">
                            <span :class="amountClass(data)">{{ formatters.fmtAmount(data) }}</span>
                        </template>
                    </Column>

                    <Column field="balance_after" header="Saldo após" style="width: 100px">
                        <template #body="{ data }">{{ data.balance_after }}</template>
                    </Column>

                    <Column field="description" header="Descrição">
                        <template #body="{ data }">
                            <span class="text-sm">{{ data.description || '—' }}</span>
                        </template>
                    </Column>

                    <Column field="price_cents" header="Valor" style="width: 110px">
                        <template #body="{ data }">
                            <span v-if="data.price_cents">{{ formatters.fmtBRL(data.price_cents) }}</span>
                            <span v-else class="text-surface-400">—</span>
                        </template>
                    </Column>

                    <Column field="payment_reference" header="Referência" style="max-width: 180px">
                        <template #body="{ data }">
                            <span class="text-xs text-surface-500 font-mono">{{ data.payment_reference || '—' }}</span>
                        </template>
                    </Column>
                </DataTable>
            </template>
        </Card>
    </div>
</template>
