/*
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/composables/useAddonExtrato.js
| Data: 2026
| Local: São Carlos/SP — Brasil
|--------------------------------------------------------------------------
| © 2026 — Todos os direitos reservados
|--------------------------------------------------------------------------
*/

import { ref, computed } from 'vue';
import { supabase } from '@/lib/supabase/client';
import { useTenantStore } from '@/stores/tenantStore';

// ─── helpers de período ─────────────────────────────────────────────────────

function startOfDay(d) {
    const x = new Date(d);
    x.setHours(0, 0, 0, 0);
    return x;
}

function endOfDay(d) {
    const x = new Date(d);
    x.setHours(23, 59, 59, 999);
    return x;
}

function resolveDateRange(preset, customRange) {
    const now = new Date();
    if (preset === 'thisMonth') {
        const start = new Date(now.getFullYear(), now.getMonth(), 1);
        return { from: startOfDay(start), to: endOfDay(now) };
    }
    if (preset === 'lastMonth') {
        const start = new Date(now.getFullYear(), now.getMonth() - 1, 1);
        const end = new Date(now.getFullYear(), now.getMonth(), 0);
        return { from: startOfDay(start), to: endOfDay(end) };
    }
    if (preset === 'last90') {
        const start = new Date(now);
        start.setDate(start.getDate() - 90);
        return { from: startOfDay(start), to: endOfDay(now) };
    }
    if (preset === 'custom' && Array.isArray(customRange) && customRange[0] && customRange[1]) {
        return { from: startOfDay(customRange[0]), to: endOfDay(customRange[1]) };
    }
    // fallback: thisMonth
    const start = new Date(now.getFullYear(), now.getMonth(), 1);
    return { from: startOfDay(start), to: endOfDay(now) };
}

// ─── sanitização de busca ───────────────────────────────────────────────────

function sanitizeSearch(raw) {
    if (typeof raw !== 'string') return '';
    const trimmed = raw.trim();
    if (!trimmed) return '';
    // limite defensivo para não enviar termos absurdos pro client-side filter
    return trimmed.slice(0, 120).toLowerCase();
}

// ─── composable ─────────────────────────────────────────────────────────────

export function useAddonExtrato() {
    const tenantStore = useTenantStore();

    const transactions = ref([]);
    const balances = ref({}); // { sms: {balance, total_purchased, total_consumed}, ... }
    const loading = ref(false);
    const error = ref(null);

    const filters = ref({
        periodPreset: 'thisMonth',
        customRange: null, // [Date, Date]
        addonTypes: [], // [] = todos
        movementTypes: [], // [] = todos
        search: ''
    });

    const dateRange = computed(() => resolveDateRange(filters.value.periodPreset, filters.value.customRange));

    async function load() {
        const tenantId = tenantStore.activeTenantId;
        if (!tenantId) {
            transactions.value = [];
            error.value = new Error('Tenant ativo inválido.');
            return;
        }

        loading.value = true;
        error.value = null;

        try {
            const { from, to } = dateRange.value;

            let query = supabase
                .from('addon_transactions')
                .select('id, created_at, addon_type, type, amount, balance_before, balance_after, description, payment_method, payment_reference, price_cents, currency, queue_id')
                .eq('tenant_id', tenantId)
                .gte('created_at', from.toISOString())
                .lte('created_at', to.toISOString())
                .order('created_at', { ascending: false })
                .limit(5000);

            if (filters.value.addonTypes.length > 0) {
                query = query.in('addon_type', filters.value.addonTypes);
            }
            if (filters.value.movementTypes.length > 0) {
                query = query.in('type', filters.value.movementTypes);
            }

            const { data, error: qErr } = await query;
            if (qErr) throw qErr;
            transactions.value = data ?? [];
        } catch (err) {
            error.value = err;
            transactions.value = [];
        } finally {
            loading.value = false;
        }
    }

    async function loadBalances() {
        const tenantId = tenantStore.activeTenantId;
        if (!tenantId) {
            balances.value = {};
            return;
        }
        const { data } = await supabase
            .from('addon_credits')
            .select('addon_type, balance, total_purchased, total_consumed, low_balance_threshold, expires_at')
            .eq('tenant_id', tenantId)
            .eq('is_active', true);
        const map = {};
        for (const c of data ?? []) map[c.addon_type] = c;
        balances.value = map;
    }

    // filtro client-side de busca textual (sobre server-side result)
    const rows = computed(() => {
        const q = sanitizeSearch(filters.value.search);
        if (!q) return transactions.value;
        return transactions.value.filter((r) => {
            const ref = (r.payment_reference || '').toLowerCase();
            const desc = (r.description || '').toLowerCase();
            const method = (r.payment_method || '').toLowerCase();
            return ref.includes(q) || desc.includes(q) || method.includes(q);
        });
    });

    const summary = computed(() => {
        let purchasedCredits = 0;
        let purchasedCents = 0;
        let consumedCredits = 0;
        let adjustedCredits = 0;
        let refundedCredits = 0;

        for (const r of rows.value) {
            const amt = Number(r.amount) || 0;
            switch (r.type) {
                case 'purchase':
                    purchasedCredits += Math.abs(amt);
                    purchasedCents += Number(r.price_cents) || 0;
                    break;
                case 'consumption':
                    consumedCredits += Math.abs(amt);
                    break;
                case 'adjustment':
                    adjustedCredits += amt; // mantém sinal
                    break;
                case 'refund':
                    refundedCredits += Math.abs(amt);
                    break;
                default:
                    break;
            }
        }

        return {
            purchasedCredits,
            purchasedCents,
            consumedCredits,
            adjustedCredits,
            refundedCredits,
            totalRows: rows.value.length
        };
    });

    return {
        transactions,
        rows,
        balances,
        filters,
        dateRange,
        loading,
        error,
        summary,
        load,
        loadBalances
    };
}
