/*
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Arquivo: src/features/financeiro/composables/useFinancialRecords.js
|
| Thin wrapper sobre financialRecordsRepository (composable-blueprint Tipo A).
| Substitui src/composables/useFinancialRecords.js quando callers migrarem.
|
| Mantém as mesmas funções públicas + computeds (summary) — drop-in
| replacement quando hora chegar.
|--------------------------------------------------------------------------
*/
import { ref, computed } from 'vue';
import {
    list as repoList,
    getById,
    listByEvent,
    createForSession,
    createManual,
    markAsPaid as repoMarkAsPaid,
    markAsUnpaid as repoMarkAsUnpaid,
    cancel as repoCancel,
    update as repoUpdate
} from '@/features/financeiro/services/financialRecordsRepository';

export function useFinancialRecords() {
    const records = ref([]);
    const total = ref(0);
    const loading = ref(false);
    const error = ref('');

    // ── computed: resumo financeiro ──────────────────────────────────────
    const summary = computed(() => {
        const now = new Date();
        const thisYear = now.getFullYear();
        const thisMonth = now.getMonth();

        const countByStatus = { pending: 0, paid: 0, overdue: 0, cancelled: 0 };
        let totalPending = 0;
        let totalOverdue = 0;
        let totalPaidThisMonth = 0;

        for (const r of records.value) {
            countByStatus[r.status] = (countByStatus[r.status] ?? 0) + 1;
            if (r.status === 'pending') totalPending += r.final_amount ?? r.amount ?? 0;
            if (r.status === 'overdue') totalOverdue += r.final_amount ?? r.amount ?? 0;
            if (r.status === 'paid' && r.paid_at) {
                const d = new Date(r.paid_at);
                if (d.getFullYear() === thisYear && d.getMonth() === thisMonth) {
                    totalPaidThisMonth += r.final_amount ?? r.amount ?? 0;
                }
            }
        }
        return { totalPending, totalOverdue, totalPaidThisMonth, countByStatus };
    });

    async function fetchRecords(filters = {}) {
        loading.value = true;
        error.value = '';
        try {
            const result = await repoList(filters);
            records.value = result.rows;
            total.value = result.total;
            return result;
        } catch (e) {
            error.value = e?.message || 'Erro ao carregar registros financeiros.';
            records.value = [];
            total.value = 0;
            return { rows: [], total: 0 };
        } finally {
            loading.value = false;
        }
    }

    async function fetchByEvent(eventId) {
        try {
            return await listByEvent(eventId);
        } catch (e) {
            error.value = e?.message || 'Erro ao buscar records do evento.';
            return [];
        }
    }

    async function fetchById(recordId) {
        try {
            return await getById(recordId);
        } catch (e) {
            error.value = e?.message || 'Erro ao buscar record.';
            return null;
        }
    }

    async function createRecord(payload) {
        loading.value = true;
        error.value = '';
        try {
            const data = await createForSession(payload);
            await fetchRecords();
            return { ok: true, data };
        } catch (e) {
            error.value = e?.message || 'Erro ao criar cobrança.';
            return { ok: false, error: e?.message };
        } finally {
            loading.value = false;
        }
    }

    async function createManualRecord(payload) {
        loading.value = true;
        error.value = '';
        try {
            const data = await createManual(payload);
            records.value = [data, ...records.value];
            return { ok: true, data };
        } catch (e) {
            error.value = e?.message || 'Erro ao criar lançamento manual.';
            return { ok: false, error: e?.message };
        } finally {
            loading.value = false;
        }
    }

    async function markAsPaid(recordId, paymentMethod) {
        error.value = '';
        try {
            await repoMarkAsPaid(recordId, paymentMethod);
            const idx = records.value.findIndex((r) => r.id === recordId);
            if (idx !== -1) {
                records.value[idx] = {
                    ...records.value[idx],
                    status: 'paid',
                    paid_at: new Date().toISOString(),
                    payment_method: paymentMethod
                };
            }
            return { ok: true };
        } catch (e) {
            error.value = e?.message || 'Erro ao marcar como pago.';
            return { ok: false, error: e?.message };
        }
    }

    async function markAsUnpaid(recordId) {
        error.value = '';
        try {
            await repoMarkAsUnpaid(recordId);
            const idx = records.value.findIndex((r) => r.id === recordId);
            if (idx !== -1) {
                records.value[idx] = {
                    ...records.value[idx],
                    status: 'pending',
                    paid_at: null,
                    payment_method: null
                };
            }
            return { ok: true };
        } catch (e) {
            error.value = e?.message || 'Erro ao reverter pagamento.';
            return { ok: false, error: e?.message };
        }
    }

    async function cancelRecord(recordId, opts = {}) {
        error.value = '';
        try {
            await repoCancel(recordId, opts);
            const idx = records.value.findIndex((r) => r.id === recordId);
            if (idx !== -1) {
                records.value[idx] = { ...records.value[idx], status: 'cancelled' };
            }
            return { ok: true };
        } catch (e) {
            error.value = e?.message || 'Erro ao cancelar registro.';
            return { ok: false, error: e?.message };
        }
    }

    async function updateRecord(recordId, patch) {
        loading.value = true;
        error.value = '';
        try {
            const updated = await repoUpdate(recordId, patch);
            const idx = records.value.findIndex((r) => r.id === recordId);
            if (idx >= 0) records.value[idx] = updated;
            return { ok: true, data: updated };
        } catch (e) {
            error.value = e?.message || 'Erro ao atualizar registro.';
            return { ok: false, error: e?.message };
        } finally {
            loading.value = false;
        }
    }

    return {
        records,
        total,
        loading,
        error,
        summary,
        fetchRecords,
        fetchByEvent,
        fetchById,
        createRecord,
        createManualRecord,
        markAsPaid,
        markAsUnpaid,
        cancelRecord,
        updateRecord
    };
}
