/*
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Arquivo: src/layout/melissa/composables/useMelissaAgendaHistorico.js
| Data: 2026-05-04
|
| Histórico recente de ações na agenda do terapeuta logado.
|
| Lê de `audit_logs` (populado automaticamente pela trigger
| `trg_audit_agenda_eventos`). Não precisa criar nada — todas as ações
| INSERT/UPDATE/DELETE em agenda_eventos já viram linhas auditadas.
|
| Filtros aplicados:
|   - entity_type = 'agenda_eventos'
|   - user_id = uid do user logado (mostra só ações dele)
|   - created_at >= 7 dias atrás
|   - tenant_id = tenant ativo
|   - LIMIT 20 (mais recentes primeiro)
|
| Pra exibir nome do paciente, fazemos um lookup separado em `patients`
| usando os IDs extraídos de new_values/old_values (não dá pra fazer JOIN
| na audit_logs porque entity_id é dinâmico).
|
| Returns:
|   - entries: ref de objetos normalizados:
|       { id, kind, label, when, paciente, evento_id, raw }
|     onde kind ∈ { 'create' | 'move' | 'status' | 'edit' | 'delete' }
|   - loading: ref<boolean>
|   - refetch: function()
|--------------------------------------------------------------------------
*/
import { ref } from 'vue';
import { supabase } from '@/lib/supabase/client';
import { tenantDb } from '@/lib/supabase/tenantClient';
import { useTenantStore } from '@/stores/tenantStore';

const STATUS_LABEL = {
    agendado: 'Agendado',
    realizado: 'Realizada',
    realizada: 'Realizada',
    faltou: 'Falta',
    cancelado: 'Cancelada',
    cancelada: 'Cancelada',
    remarcar: 'Remarcar',
    remarcado: 'Remarcado',
    confirmado: 'Confirmada'
};

function fmtTime(iso) {
    if (!iso) return '';
    const d = new Date(iso);
    return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;
}
function fmtDateBR(iso) {
    if (!iso) return '';
    const d = new Date(iso);
    return `${String(d.getDate()).padStart(2, '0')}/${String(d.getMonth() + 1).padStart(2, '0')}`;
}

// Classifica a entrada pra um dos 5 "kinds" visuais. Decisão por
// changed_fields quando action=update — ordem importa: hora primeiro
// (mais frequente em movimentação), depois status, depois "edit" genérico.
function classify(row) {
    const action = String(row.action || '').toLowerCase();
    if (action === 'insert') return 'create';
    if (action === 'delete') return 'delete';
    if (action === 'update') {
        const fields = new Set(row.changed_fields || []);
        if (fields.has('inicio_em') || fields.has('fim_em')) return 'move';
        if (fields.has('status')) return 'status';
        return 'edit';
    }
    return 'edit';
}

function buildLabel(kind, row) {
    const oldV = row.old_values || {};
    const newV = row.new_values || {};
    switch (kind) {
        case 'create': {
            const ini = newV.inicio_em ? `${fmtDateBR(newV.inicio_em)} ${fmtTime(newV.inicio_em)}` : '—';
            return `Criou sessão em ${ini}`;
        }
        case 'delete': {
            const ini = oldV.inicio_em ? `${fmtDateBR(oldV.inicio_em)} ${fmtTime(oldV.inicio_em)}` : '—';
            return `Removeu sessão de ${ini}`;
        }
        case 'move': {
            const from = oldV.inicio_em ? `${fmtDateBR(oldV.inicio_em)} ${fmtTime(oldV.inicio_em)}` : '—';
            const to   = newV.inicio_em ? `${fmtDateBR(newV.inicio_em)} ${fmtTime(newV.inicio_em)}` : '—';
            return `Moveu ${from} → ${to}`;
        }
        case 'status': {
            const lbl = STATUS_LABEL[String(newV.status || '').toLowerCase()] || newV.status || '—';
            return `Status: ${lbl}`;
        }
        case 'edit':
        default: {
            const fields = (row.changed_fields || []).filter((f) => f !== 'updated_at');
            if (!fields.length) return 'Editou';
            return `Editou ${fields.join(', ')}`;
        }
    }
}

// Resolve o ID do paciente a partir de new_values/old_values (delete usa OLD).
function extractPatientId(row) {
    return row.new_values?.patient_id || row.old_values?.patient_id || null;
}

export function useMelissaAgendaHistorico(opts = {}) {
    const limit = opts.limit ?? 20;
    const days = opts.days ?? 7;

    const tenantStore = useTenantStore();
    const entries = ref([]);
    const loading = ref(false);
    const error = ref('');

    async function _ensureUid() {
        const { data: ses } = await supabase.auth.getSession();
        if (ses?.session?.user?.id) return ses.session.user.id;
        const { data, error: err } = await supabase.auth.getUser();
        if (err) return null;
        return data?.user?.id || null;
    }

    async function refetch() {
        loading.value = true;
        error.value = '';
        try {
            const userId = await _ensureUid();
            if (typeof tenantStore.ensureLoaded === 'function') {
                await tenantStore.ensureLoaded();
            }
            const tid = tenantStore.activeTenantId || tenantStore.tenantId || null;
            if (!userId || !tid) {
                entries.value = [];
                return;
            }

            const since = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();

            const { data: rows, error: err } = await supabase
                .from('audit_logs')
                .select('id, action, entity_id, changed_fields, old_values, new_values, created_at, user_id, tenant_id')
                .eq('entity_type', 'agenda_eventos')
                .eq('user_id', userId)
                .eq('tenant_id', tid)
                .gte('created_at', since)
                .order('created_at', { ascending: false })
                .limit(limit);

            if (err) throw err;

            const list = rows || [];

            // Resolve nomes dos pacientes em uma única query.
            const patientIds = [...new Set(list.map(extractPatientId).filter(Boolean))];
            const patientMap = new Map();
            if (patientIds.length) {
                const { data: pats } = await tenantDb().from('patients')
                    .select('id, nome_completo')
                    .in('id', patientIds);
                for (const p of pats || []) patientMap.set(p.id, p.nome_completo);
            }

            entries.value = list.map((r) => {
                const kind = classify(r);
                const pid = extractPatientId(r);
                return {
                    id: r.id,
                    kind,
                    label: buildLabel(kind, r),
                    when: r.created_at,
                    paciente: pid ? (patientMap.get(pid) || '') : '',
                    evento_id: r.entity_id,
                    raw: r
                };
            });
        } catch (e) {
            error.value = e?.message || 'Falha ao carregar histórico';
            entries.value = [];
            // eslint-disable-next-line no-console
            console.warn('[useMelissaAgendaHistorico]', e);
        } finally {
            loading.value = false;
        }
    }

    return { entries, loading, error, refetch };
}
