/*
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/composables/useClinicKPIs.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 { tenantDb } from '@/lib/supabase/tenantClient';
import { useTenantStore } from '@/stores/tenantStore';

function startOfMonth(d = new Date()) {
    return new Date(d.getFullYear(), d.getMonth(), 1, 0, 0, 0, 0);
}

function endOfMonth(d = new Date()) {
    return new Date(d.getFullYear(), d.getMonth() + 1, 0, 23, 59, 59, 999);
}

function addMonths(d, n) {
    return new Date(d.getFullYear(), d.getMonth() + n, 1);
}

function monthLabel(d) {
    return d.toLocaleDateString('pt-BR', { month: 'short', year: '2-digit' });
}

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

    const loading = ref(false);
    const error = ref(null);

    // totais do mês corrente
    const mrrCurrentCents = ref(0); // receita recebida no mês
    const overdueCents = ref(0);
    const overdueCount = ref(0);
    const pendingCents = ref(0);

    // pacientes
    const activePatients = ref(0);
    const inactivePatients = ref(0);
    const totalPatients = ref(0);

    // sessões
    const sessionsDone = ref(0);
    const sessionsCancelled = ref(0);
    const sessionsNoShow = ref(0);
    const sessionsScheduled = ref(0);

    // receita últimos 6 meses
    const revenueSeries = ref([]); // [{ label, received, due }]

    // top 5 pacientes (por valor recebido últimos 6 meses)
    const topPatients = ref([]); // [{ patient_id, nome_completo, total }]

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

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

        const now = new Date();
        const monthStart = startOfMonth(now).toISOString();
        const monthEnd = endOfMonth(now).toISOString();
        const sixMonthsAgo = startOfMonth(addMonths(now, -5)).toISOString();

        try {
            const [finRes, pendRes, patRes, eventRes, finSeriesRes] = await Promise.all([
                // 1) financial_records PAGO no mês (para MRR)
                tenantDb().from('financial_records')
                    .select('final_amount, patient_id')
                    
                    .eq('status', 'paid')
                    .gte('paid_at', monthStart)
                    .lte('paid_at', monthEnd),

                // 2) financial_records pending/overdue (qualquer data)
                tenantDb().from('financial_records')
                    .select('status, final_amount')
                    
                    .in('status', ['pending', 'overdue']),

                // 3) patients por status
                tenantDb().from('patients')
                    .select('status')
                    ,

                // 4) eventos de agenda no mês (para realizado/cancelado/faltou)
                tenantDb().from('agenda_eventos')
                    .select('status, tipo')
                    
                    .gte('inicio_em', monthStart)
                    .lte('inicio_em', monthEnd)
                    .neq('tipo', 'bloqueio'),

                // 5) financial_records pagos últimos 6 meses (série + top pacientes)
                tenantDb().from('financial_records')
                    .select('final_amount, paid_at, patient_id, patients!patient_id(nome_completo)')
                    
                    .eq('status', 'paid')
                    .gte('paid_at', sixMonthsAgo)
                    .lte('paid_at', monthEnd)
            ]);

            if (finRes.error) throw finRes.error;
            if (pendRes.error) throw pendRes.error;
            if (patRes.error) throw patRes.error;
            if (eventRes.error) throw eventRes.error;
            if (finSeriesRes.error) throw finSeriesRes.error;

            // MRR do mês (em centavos ou reais? seguindo financial_records.amount está em number/int; tratar como BRL)
            mrrCurrentCents.value = 0;
            for (const r of finRes.data ?? []) {
                mrrCurrentCents.value += Number(r.final_amount) || 0;
            }

            // pending / overdue
            overdueCents.value = 0;
            overdueCount.value = 0;
            pendingCents.value = 0;
            for (const r of pendRes.data ?? []) {
                const v = Number(r.final_amount) || 0;
                if (r.status === 'overdue') {
                    overdueCents.value += v;
                    overdueCount.value += 1;
                } else if (r.status === 'pending') {
                    pendingCents.value += v;
                }
            }

            // pacientes
            totalPatients.value = (patRes.data ?? []).length;
            activePatients.value = 0;
            inactivePatients.value = 0;
            for (const p of patRes.data ?? []) {
                if (p.status === 'Ativo') activePatients.value += 1;
                else if (p.status === 'Inativo' || p.status === 'Arquivado') inactivePatients.value += 1;
            }

            // sessões
            sessionsDone.value = 0;
            sessionsCancelled.value = 0;
            sessionsNoShow.value = 0;
            sessionsScheduled.value = 0;
            for (const ev of eventRes.data ?? []) {
                sessionsScheduled.value += 1;
                if (ev.status === 'realizado') sessionsDone.value += 1;
                else if (ev.status === 'cancelado') sessionsCancelled.value += 1;
                else if (ev.status === 'faltou') sessionsNoShow.value += 1;
            }

            // série 6 meses + top 5 pacientes
            const monthBuckets = {};
            for (let i = 5; i >= 0; i--) {
                const d = startOfMonth(addMonths(now, -i));
                const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`;
                monthBuckets[key] = { label: monthLabel(d), received: 0 };
            }
            const patientTotals = new Map();

            for (const r of finSeriesRes.data ?? []) {
                if (!r.paid_at) continue;
                const d = new Date(r.paid_at);
                const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`;
                const v = Number(r.final_amount) || 0;
                if (monthBuckets[key]) {
                    monthBuckets[key].received += v;
                }
                if (r.patient_id) {
                    const prev = patientTotals.get(r.patient_id) || { nome: r.patients?.nome_completo || '—', total: 0 };
                    patientTotals.set(r.patient_id, { nome: prev.nome, total: prev.total + v });
                }
            }

            revenueSeries.value = Object.values(monthBuckets);

            topPatients.value = [...patientTotals.entries()]
                .map(([patient_id, v]) => ({ patient_id, nome_completo: v.nome, total: v.total }))
                .sort((a, b) => b.total - a.total)
                .slice(0, 5);
        } catch (err) {
            error.value = err;
        } finally {
            loading.value = false;
        }
    }

    const avgTicket = computed(() => {
        if (sessionsDone.value === 0) return 0;
        return mrrCurrentCents.value / sessionsDone.value;
    });

    const noShowRate = computed(() => {
        const closed = sessionsDone.value + sessionsCancelled.value + sessionsNoShow.value;
        if (closed === 0) return null;
        return Math.round((sessionsNoShow.value / closed) * 100);
    });

    return {
        loading,
        error,
        mrrCurrentCents,
        overdueCents,
        overdueCount,
        pendingCents,
        activePatients,
        inactivePatients,
        totalPatients,
        sessionsDone,
        sessionsCancelled,
        sessionsNoShow,
        sessionsScheduled,
        avgTicket,
        noShowRate,
        revenueSeries,
        topPatients,
        load
    };
}
