/*
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Arquivo: src/features/patients/composables/usePatientFinancial.js
|
| Lançamentos financeiros (financial_records) do paciente. type=receita,
| limit 100. paid_at NULL = pendente, preenchido = pago.
| "Vencido" = paid_at IS NULL AND due_date < hoje.
| Computeds: kpis (em aberto, atrasado, total, último pago, status financeiro).
|--------------------------------------------------------------------------
*/
import { ref, computed } from 'vue';
import {
    listFinancialRecordsByPatient,
    createFinancialRecord,
    markFinancialRecordPaid,
    markFinancialRecordUnpaid
} from '@/features/patients/services/patientsRepository';

export function usePatientFinancial() {
    const records = ref([]);
    const loading = ref(false);
    const error = ref('');
    const busy = ref(false);
    // Dentro da function — não vaza entre instâncias (audit alta resolvida)
    let _lastPatientId = null;

    async function load(patientId) {
        _lastPatientId = patientId || null;
        if (!patientId) {
            records.value = [];
            return;
        }
        loading.value = true;
        error.value = '';
        records.value = [];
        try {
            records.value = await listFinancialRecordsByPatient(patientId);
        } catch (e) {
            error.value = e?.message || 'Falha ao carregar lançamentos.';
            records.value = [];
        } finally {
            loading.value = false;
        }
    }

    const totalRecebido = computed(() =>
        records.value
            .filter((r) => r.paid_at)
            .reduce((acc, r) => acc + Number(r.amount || 0), 0)
    );

    const totalEmAberto = computed(() =>
        records.value
            .filter((r) => !r.paid_at)
            .reduce((acc, r) => acc + Number(r.amount || 0), 0)
    );

    const totalAtrasado = computed(() => {
        const today = new Date().toISOString().slice(0, 10);
        return records.value
            .filter((r) => !r.paid_at && r.due_date && r.due_date < today)
            .reduce((acc, r) => acc + Number(r.amount || 0), 0);
    });

    const ultimoPago = computed(() => {
        const pagos = records.value.filter((r) => r.paid_at);
        if (!pagos.length) return null;
        return [...pagos].sort((a, b) => new Date(b.paid_at) - new Date(a.paid_at))[0];
    });

    /**
     * Status financeiro detalhado pra KPI da Visão Geral.
     */
    const statusFinanceiro = computed(() => {
        const recs = records.value;
        if (!recs?.length) {
            return { emDia: null, proxVenc: null, totalPendente: 0, totalPago: 0, vencidos: 0 };
        }
        const now = Date.now();
        const pendentes = recs.filter((r) => !r.paid_at);
        const pagos = recs.filter((r) => !!r.paid_at);
        const vencidos = pendentes.filter(
            (r) => r.due_date && new Date(r.due_date + 'T23:59:59').getTime() < now
        );
        const proxVenc =
            pendentes
                .filter((r) => r.due_date && new Date(r.due_date + 'T00:00:00').getTime() >= now)
                .sort((a, b) => new Date(a.due_date) - new Date(b.due_date))[0] || null;
        const totalPendente = pendentes.reduce((acc, r) => acc + (Number(r.amount) || 0), 0);
        const totalPago = pagos.reduce((acc, r) => acc + (Number(r.amount) || 0), 0);
        return {
            emDia: vencidos.length === 0,
            proxVenc,
            totalPendente,
            totalPago,
            vencidos: vencidos.length
        };
    });

    const recordsOrdenados = computed(() =>
        [...records.value].sort((a, b) => {
            const da = a.due_date || a.created_at;
            const db = b.due_date || b.created_at;
            return new Date(db) - new Date(da);
        })
    );

    async function markPaid(recordId) {
        if (!recordId || busy.value) return { ok: false, error: 'busy' };
        busy.value = true;
        try {
            await markFinancialRecordPaid(recordId);
            if (_lastPatientId) await load(_lastPatientId);
            return { ok: true };
        } catch (e) {
            return { ok: false, error: e?.message || 'Erro ao marcar como pago' };
        } finally {
            busy.value = false;
        }
    }

    async function createRecord(patientId, payload = {}) {
        if (!patientId || busy.value) return { ok: false, error: 'busy' };
        if (!payload?.amount || Number.isNaN(Number(payload.amount))) {
            return { ok: false, error: 'Valor inválido' };
        }
        busy.value = true;
        try {
            const data = await createFinancialRecord(patientId, payload);
            if (_lastPatientId) await load(_lastPatientId);
            return { ok: true, data };
        } catch (e) {
            return { ok: false, error: e?.message || 'Erro ao criar lançamento' };
        } finally {
            busy.value = false;
        }
    }

    async function markUnpaid(recordId) {
        if (!recordId || busy.value) return { ok: false, error: 'busy' };
        busy.value = true;
        try {
            await markFinancialRecordUnpaid(recordId);
            if (_lastPatientId) await load(_lastPatientId);
            return { ok: true };
        } catch (e) {
            return { ok: false, error: e?.message || 'Erro ao reverter pagamento' };
        } finally {
            busy.value = false;
        }
    }

    return {
        records,
        loading,
        error,
        busy,
        load,
        totalRecebido,
        totalEmAberto,
        totalAtrasado,
        ultimoPago,
        statusFinanceiro,
        recordsOrdenados,
        markPaid,
        markUnpaid,
        createRecord
    };
}
