'use client'; import { useCallback } from 'react'; import type { ExportData, ExportFormat } from '@/types/export'; import type { AnalysisResult } from '@/types'; export function useExport() { // Generate export data structure const generateExportData = useCallback( ( originalText: string, analysisResult: AnalysisResult, settings: { selectedModel: string; temperature: number; confidenceThreshold: number; enabledCategories: string[]; enabledSeverities: string[]; } ): ExportData => { const categoryCounts: Record = {}; analysisResult.errors.forEach((error) => { categoryCounts[error.category] = (categoryCounts[error.category] || 0) + 1; }); return { metadata: { exportDate: new Date().toISOString(), modelUsed: settings.selectedModel, analysisSettings: { temperature: settings.temperature, confidenceThreshold: settings.confidenceThreshold, enabledCategories: settings.enabledCategories, enabledSeverities: settings.enabledSeverities, }, }, originalText, analysisResult, summary: { totalErrors: analysisResult.errors.length, criticalCount: analysisResult.errors.filter((e) => e.severity === 'critical') .length, warningCount: analysisResult.errors.filter((e) => e.severity === 'warning') .length, suggestionCount: analysisResult.errors.filter((e) => e.severity === 'suggestion') .length, categoryCounts, }, }; }, [] ); // Export to CSV const exportToCSV = useCallback((data: ExportData): void => { const rows = [ [ 'Severity', 'Category', 'Explanation', 'Reasoning', 'Suggestion', 'Confidence', ], ]; data.analysisResult.errors.forEach((error) => { rows.push([ error.severity, error.category, `"${error.explanation.replace(/"/g, '""')}"`, error.reasoning ? `"${error.reasoning.replace(/"/g, '""')}"` : '', error.suggestion ? `"${error.suggestion.replace(/"/g, '""')}"` : '', (error.confidence * 100).toFixed(1) + '%', ]); }); const csvContent = rows.map((row) => row.join(',')).join('\n'); downloadFile( csvContent, `clinical-analysis-${new Date().toISOString().split('T')[0]}.csv`, 'text/csv' ); }, []); // Export to JSON const exportToJSON = useCallback((data: ExportData): void => { const jsonContent = JSON.stringify(data, null, 2); downloadFile( jsonContent, `clinical-analysis-${new Date().toISOString().split('T')[0]}.json`, 'application/json' ); }, []); // Export to plain text report const exportToText = useCallback((data: ExportData): void => { const lines: string[] = []; lines.push('CLINICAL NOTE ANALYSIS REPORT'); lines.push('='.repeat(50)); lines.push(''); lines.push(`Date: ${new Date(data.metadata.exportDate).toLocaleString()}`); lines.push(`Model: ${data.metadata.modelUsed}`); if (data.metadata.templateType) { lines.push(`Template: ${data.metadata.templateType}`); } lines.push(''); lines.push('SUMMARY'); lines.push('-'.repeat(50)); lines.push(`Total Errors Found: ${data.summary.totalErrors}`); lines.push(` Critical: ${data.summary.criticalCount}`); lines.push(` Warnings: ${data.summary.warningCount}`); lines.push(` Suggestions: ${data.summary.suggestionCount}`); lines.push(''); lines.push('ORIGINAL TEXT'); lines.push('-'.repeat(50)); lines.push(data.originalText); lines.push(''); if (data.analysisResult.errors.length > 0) { lines.push('DETECTED ISSUES'); lines.push('-'.repeat(50)); lines.push(''); data.analysisResult.errors.forEach((error, index) => { lines.push(`${index + 1}. [${error.severity.toUpperCase()}] ${error.category}`); lines.push(` Issue: ${error.explanation}`); if (error.reasoning) { lines.push(` Reasoning: ${error.reasoning}`); } if (error.suggestion) { lines.push(` Suggestion: ${error.suggestion}`); } lines.push(` Confidence: ${(error.confidence * 100).toFixed(1)}%`); lines.push(''); }); } else { lines.push('No issues detected.'); lines.push(''); } lines.push('='.repeat(50)); lines.push('Generated by Clinical Error Detector'); const textContent = lines.join('\n'); downloadFile( textContent, `clinical-analysis-${new Date().toISOString().split('T')[0]}.txt`, 'text/plain' ); }, []); // Export to PDF (print-friendly HTML) const exportToPDF = useCallback((data: ExportData): void => { // Create a print-friendly HTML view const printWindow = window.open('', '', 'width=800,height=600'); if (!printWindow) { alert('Please allow popups to export to PDF'); return; } const html = generatePrintHTML(data); printWindow.document.write(html); printWindow.document.close(); // Wait for content to load, then trigger print printWindow.onload = () => { printWindow.focus(); printWindow.print(); }; }, []); // Main export function const exportAnalysis = useCallback( ( format: ExportFormat, originalText: string, analysisResult: AnalysisResult, settings: { selectedModel: string; temperature: number; confidenceThreshold: number; enabledCategories: string[]; enabledSeverities: string[]; } ) => { const data = generateExportData(originalText, analysisResult, settings); switch (format) { case 'csv': exportToCSV(data); break; case 'json': exportToJSON(data); break; case 'txt': exportToText(data); break; case 'pdf': exportToPDF(data); break; } }, [generateExportData, exportToCSV, exportToJSON, exportToText, exportToPDF] ); return { exportAnalysis }; } // Utility function to download file function downloadFile(content: string, filename: string, mimeType: string) { const blob = new Blob([content], { type: mimeType }); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = filename; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); } // Generate print-friendly HTML for PDF export function generatePrintHTML(data: ExportData): string { const getSeverityColor = (severity: string) => { switch (severity) { case 'critical': return '#dc2626'; case 'warning': return '#ea580c'; case 'suggestion': return '#2563eb'; default: return '#6b7280'; } }; return ` Clinical Note Analysis Report

Clinical Note Analysis Report

Summary

${data.summary.totalErrors}
Total Issues
${data.summary.criticalCount}
Critical
${data.summary.warningCount}
Warnings
${data.summary.suggestionCount}
Suggestions

Original Clinical Note

${escapeHtml(data.originalText)}
${ data.analysisResult.errors.length > 0 ? `

Detected Issues (${data.analysisResult.errors.length})

${data.analysisResult.errors .map( (error) => `
${error.severity.toUpperCase()} ${error.category} Confidence: ${(error.confidence * 100).toFixed(1)}%
${escapeHtml(error.explanation)}
${ error.reasoning ? `
${escapeHtml(error.reasoning)}
` : '' } ${ error.suggestion ? `
💡 Suggestion:
${escapeHtml(error.suggestion)}
` : '' }
` ) .join('')} ` : '

No issues detected in the clinical note.

' } `; } function escapeHtml(text: string): string { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; }