/*
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Arquivo: src/features/patients/prontuario/composables/useClinicalNotes.js
|
| Thin wrapper sobre clinicalNotesRepository (composable-blueprint Tipo A).
| State reativo: rows, loading, error.
|
| ⚠️ Depende das migrations 0.5.B aplicadas no banco. Sem isso, qualquer
| operação retorna erro de "tabela clinical_notes não existe".
|--------------------------------------------------------------------------
*/
import { ref } from 'vue';
import {
    listForPatient,
    listForSession,
    getById,
    create as repoCreate,
    update as repoUpdate,
    softDelete as repoSoftDelete,
    restore as repoRestore,
    setPinned as repoSetPinned,
    listVersions,
    getVersion
} from '@/features/patients/prontuario/services/clinicalNotesRepository';

export function useClinicalNotes() {
    const rows = ref([]);
    const loading = ref(false);
    const error = ref('');

    async function loadForPatient(patientId, opts = {}) {
        if (!patientId) {
            rows.value = [];
            return;
        }
        loading.value = true;
        error.value = '';
        try {
            rows.value = await listForPatient(patientId, opts);
        } catch (e) {
            error.value = e?.message || 'Falha ao carregar notas clínicas.';
            rows.value = [];
        } finally {
            loading.value = false;
        }
    }

    async function loadForSession(sessionEventId, opts = {}) {
        if (!sessionEventId) {
            rows.value = [];
            return;
        }
        loading.value = true;
        error.value = '';
        try {
            rows.value = await listForSession(sessionEventId, opts);
        } catch (e) {
            error.value = e?.message || 'Falha ao carregar notas da sessão.';
            rows.value = [];
        } finally {
            loading.value = false;
        }
    }

    async function fetchById(noteId, opts = {}) {
        loading.value = true;
        error.value = '';
        try {
            return await getById(noteId, opts);
        } catch (e) {
            error.value = e?.message || 'Falha ao carregar nota.';
            return null;
        } finally {
            loading.value = false;
        }
    }

    async function create(payload) {
        loading.value = true;
        error.value = '';
        try {
            const created = await repoCreate(payload);
            // Insere no topo se pinned, senão por ordem natural (já vem com created_at = now)
            rows.value = [created, ...rows.value];
            return created;
        } catch (e) {
            error.value = e?.message || 'Falha ao criar nota.';
            throw e;
        } finally {
            loading.value = false;
        }
    }

    async function update(noteId, patch, opts = {}) {
        loading.value = true;
        error.value = '';
        try {
            const updated = await repoUpdate(noteId, patch, opts);
            const idx = rows.value.findIndex((r) => r.id === noteId);
            if (idx >= 0) rows.value[idx] = updated;
            return updated;
        } catch (e) {
            error.value = e?.message || 'Falha ao atualizar nota.';
            throw e;
        } finally {
            loading.value = false;
        }
    }

    async function softDelete(noteId, opts = {}) {
        loading.value = true;
        error.value = '';
        try {
            await repoSoftDelete(noteId, opts);
            rows.value = rows.value.filter((r) => r.id !== noteId);
            return true;
        } catch (e) {
            error.value = e?.message || 'Falha ao remover nota.';
            throw e;
        } finally {
            loading.value = false;
        }
    }

    async function restore(noteId, opts = {}) {
        loading.value = true;
        error.value = '';
        try {
            await repoRestore(noteId, opts);
            return true;
        } catch (e) {
            error.value = e?.message || 'Falha ao restaurar nota.';
            throw e;
        } finally {
            loading.value = false;
        }
    }

    async function togglePinned(noteId, pinned, opts = {}) {
        loading.value = true;
        error.value = '';
        try {
            const updated = await repoSetPinned(noteId, pinned, opts);
            const idx = rows.value.findIndex((r) => r.id === noteId);
            if (idx >= 0) rows.value[idx] = updated;
            return updated;
        } catch (e) {
            error.value = e?.message || 'Falha ao fixar nota.';
            throw e;
        } finally {
            loading.value = false;
        }
    }

    async function fetchVersions(noteId) {
        try {
            return await listVersions(noteId);
        } catch (e) {
            error.value = e?.message || 'Falha ao carregar versões.';
            return [];
        }
    }

    async function fetchVersion(noteId, versionNumber) {
        try {
            return await getVersion(noteId, versionNumber);
        } catch (e) {
            error.value = e?.message || 'Falha ao carregar versão.';
            return null;
        }
    }

    return {
        rows,
        loading,
        error,
        loadForPatient,
        loadForSession,
        fetchById,
        create,
        update,
        softDelete,
        restore,
        togglePinned,
        fetchVersions,
        fetchVersion
    };
}
