/** * Session Storage & Export Service * * Manages persistent storage of completed CBT roleplay sessions, * enabling history review, markdown report exports, and JSON backups. */ import { SavedSession, Scenario, SessionMode, Message, AnalysisResult } from '../types'; const SESSIONS_STORAGE_KEY = 'cognitive-clarity-saved-sessions'; /** * Retrieves all saved sessions from LocalStorage. */ export function getSavedSessions(): SavedSession[] { try { const raw = localStorage.getItem(SESSIONS_STORAGE_KEY); return raw ? JSON.parse(raw) : []; } catch (e) { console.error("Failed to load saved sessions", e); return []; } } /** * Saves a completed session to LocalStorage. */ export function saveSession( scenario: Scenario, mode: SessionMode, messages: Message[], finalReport?: AnalysisResult ): SavedSession { const newSession: SavedSession = { id: `session-${Date.now()}-${Math.random().toString(36).substring(2, 7)}`, scenarioId: scenario.id, scenarioTitle: scenario.title, category: scenario.category, difficulty: scenario.difficulty, timestamp: new Date().toISOString(), mode, messages, finalReport }; try { const existing = getSavedSessions(); const updated = [newSession, ...existing].slice(0, 50); // Keep last 50 sessions localStorage.setItem(SESSIONS_STORAGE_KEY, JSON.stringify(updated)); } catch (e) { console.error("Failed to save session", e); } return newSession; } /** * Deletes a session by ID. */ export function deleteSession(sessionId: string): void { try { const existing = getSavedSessions(); const filtered = existing.filter(s => s.id !== sessionId); localStorage.setItem(SESSIONS_STORAGE_KEY, JSON.stringify(filtered)); } catch (e) { console.error("Failed to delete session", e); } } /** * Generates an Apple HIG-styled Markdown summary of a CBT session report. */ export function formatSessionAsMarkdown( scenarioTitle: string, analysis: AnalysisResult, messages?: Message[] ): string { const dateStr = new Date().toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit' }); let md = `# Cognitive Clarity — Clinical CBT Session Report\n\n`; md += `**Scenario:** ${scenarioTitle}\n`; md += `**Date:** ${dateStr}\n`; md += `**Clinical Evaluation:** ${analysis.analysis.isAdaptive ? '✅ Adaptive Growth Observed' : '⚠️ Clinical Patterns / Distortions Detected'}\n`; md += `**Mastery Rating:** ${analysis.rating.score} / 5\n\n`; md += `---\n\n`; md += `## 1. Clinical Analysis\n\n`; if (analysis.analysis.distortions.length > 0) { md += `**Cognitive Distortions Identified:**\n`; analysis.analysis.distortions.forEach(d => { md += `- ${d}\n`; }); md += `\n`; } md += `**Behavioral Evidence:**\n> "${analysis.analysis.evidence}"\n\n`; md += `**Clinical Justification:**\n${analysis.rating.reason}\n\n`; md += `## 2. Cognitive Reframing & Tactical Steps\n\n`; md += `**Master Reframe:**\n> "${analysis.suggestions.alternativeThought}"\n\n`; md += `**Homework & Behavioral Step:**\n${analysis.suggestions.behavioralStep}\n\n`; if (messages && messages.length > 0) { md += `---\n\n## 3. Session Transcript\n\n`; messages.forEach(m => { const sender = m.role === 'user' ? 'You' : 'AI Partner'; md += `**[${sender}]**: ${m.text}\n\n`; }); } return md; } /** * Triggers a client-side file download of text content. */ export function downloadFile(content: string, fileName: string, contentType: string): void { const blob = new Blob([content], { type: contentType }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = fileName; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); }