/* |-------------------------------------------------------------------------- | Agência PSI |-------------------------------------------------------------------------- | Criado e desenvolvido por Leonardo Nohama | | Tecnologia aplicada à escuta. | Estrutura para o cuidado. | | Arquivo: src/features/documents/composables/useDocumentGenerate.js | Data: 2026 | Local: São Carlos/SP — Brasil |-------------------------------------------------------------------------- | © 2026 — Todos os direitos reservados |-------------------------------------------------------------------------- */ import { ref, computed } from 'vue'; import { loadAllVariables, fillTemplate, buildFullHtml, generatePdfBlob, generateAndDownloadPdf, printDocument as printPdf, saveGeneratedDocument, listGeneratedDocuments } from '@/services/DocumentGenerate.service'; import { getTemplate } from '@/services/DocumentTemplates.service'; // ── Composable ────────────────────────────────────────────── export function useDocumentGenerate() { const loading = ref(false); const error = ref(null); const generatedDocs = ref([]); // Dados carregados para preenchimento const variables = ref({}); const selectedTemplate = ref(null); const previewHtml = ref(''); // ── Carregar variaveis do paciente/sessao ─────────────── async function loadVariables(patientId, agendaEventoId = null) { loading.value = true; error.value = null; try { variables.value = await loadAllVariables(patientId, agendaEventoId); // Hint útil pra diagnostico: se vier objeto mas todos campos vazios, // sinaliza que perfil/clínica/paciente provavelmente nao tem dados. const filled = Object.values(variables.value).filter(v => String(v ?? '').trim() !== '').length; if (filled === 0) { error.value = 'Nenhum dado foi encontrado pra auto-preencher. Verifique o cadastro do paciente, perfil e clínica.'; } } catch (e) { console.error('[useDocumentGenerate.loadVariables] falha:', e); error.value = e?.message || 'Erro ao carregar dados pra preenchimento.'; variables.value = {}; } finally { loading.value = false; } } // ── Selecionar template e gerar preview ───────────────── async function selectTemplate(templateId) { loading.value = true; error.value = null; try { selectedTemplate.value = await getTemplate(templateId); updatePreview(); } catch (e) { error.value = e?.message || 'Erro ao carregar template.'; selectedTemplate.value = null; previewHtml.value = ''; } finally { loading.value = false; } } // ── Atualizar preview ─────────────────────────────────── function updatePreview() { if (!selectedTemplate.value) { previewHtml.value = ''; return; } previewHtml.value = buildFullHtml(selectedTemplate.value, variables.value); } // ── Atualizar variavel individual ─────────────────────── function setVariable(key, value) { variables.value[key] = value; updatePreview(); } // ── Gerar PDF (client-side) ──────────────────────────── /** * Gera PDF blob, salva no Storage + banco. * @param {string} patientId * @param {string|null} editingDocId - se setado, UPDATE no doc existente * (in-place replace de PDF + metadados, preserva documents.id e audit). */ async function generateAndSave(patientId, editingDocId = null) { if (!selectedTemplate.value) throw new Error('Nenhum template selecionado.'); loading.value = true; error.value = null; try { const templateNome = selectedTemplate.value.nome_template || 'documento'; // Gera PDF blob const blob = await generatePdfBlob(selectedTemplate.value, variables.value); // Salva no Storage + banco (generated-docs + documents) const result = await saveGeneratedDocument({ templateId: selectedTemplate.value.id, patientId, dadosPreenchidos: { ...variables.value }, pdfBlob: blob, templateNome, templateTipo: selectedTemplate.value.tipo, editingDocId }); generatedDocs.value.unshift(result); return result; } catch (e) { error.value = e?.message || 'Erro ao gerar documento.'; throw e; } finally { loading.value = false; } } /** * Gera somente o PDF e faz download, sem salvar no banco. */ async function downloadOnly() { if (!selectedTemplate.value) return; loading.value = true; error.value = null; try { const templateNome = selectedTemplate.value?.nome_template || 'documento'; const filename = `${templateNome.replace(/\s+/g, '_')}_${Date.now()}.pdf`; await generateAndDownloadPdf(selectedTemplate.value, variables.value, filename); } catch (e) { error.value = e?.message || 'Erro ao gerar PDF.'; throw e; } finally { loading.value = false; } } /** * Abre PDF em nova aba para impressao. */ function printDocument() { if (!selectedTemplate.value) return; printPdf(selectedTemplate.value, variables.value); } // ── Carregar historico de documentos gerados ──────────── async function fetchGeneratedDocs(patientId) { loading.value = true; error.value = null; try { generatedDocs.value = await listGeneratedDocuments(patientId); } catch (e) { error.value = e?.message || 'Erro ao carregar documentos gerados.'; generatedDocs.value = []; } finally { loading.value = false; } } // ── Reset ─────────────────────────────────────────────── function reset() { selectedTemplate.value = null; variables.value = {}; previewHtml.value = ''; error.value = null; } return { // State loading, error, variables, selectedTemplate, previewHtml, generatedDocs, // Actions loadVariables, selectTemplate, updatePreview, setVariable, generateAndSave, downloadOnly, printDocument, fetchGeneratedDocs, reset }; }