/**
 * Session Messages Service
 *
 * Persists session messages/events to SQLite for transcript restoration.
 * Messages are saved immediately when received to prevent data loss.
 */
import { createTimestamp } from '@stoneforge/core';
function dbToMessage(row) {
    return {
        id: row.id,
        sessionId: row.session_id,
        agentId: row.agent_id,
        type: row.type,
        content: row.content ?? undefined,
        toolName: row.tool_name ?? undefined,
        toolInput: row.tool_input ?? undefined,
        toolOutput: row.tool_output ?? undefined,
        isError: row.is_error === 1,
        createdAt: row.created_at,
    };
}
export function createSessionMessageService(storage) {
    return {
        saveMessage(message) {
            const createdAt = message.createdAt ?? createTimestamp();
            // Explicitly construct params with all 10 values for the 10 SQL placeholders
            // Order must match: id, session_id, agent_id, type, content, tool_name, tool_input, tool_output, is_error, created_at
            const id = message.id ?? '';
            const sessionId = message.sessionId ?? '';
            const agentId = message.agentId ?? '';
            const type = message.type ?? 'system';
            // SAFETY: Ensure content is a string or null, never an object (SQLite can't bind objects)
            const content = typeof message.content === 'string' ? message.content : null;
            const toolName = typeof message.toolName === 'string' ? message.toolName : null;
            const toolInput = typeof message.toolInput === 'string' ? message.toolInput : null;
            const toolOutput = typeof message.toolOutput === 'string' ? message.toolOutput : null;
            const isError = message.isError ? 1 : 0;
            storage.run('INSERT OR REPLACE INTO session_messages (id, session_id, agent_id, type, content, tool_name, tool_input, tool_output, is_error, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [id, sessionId, agentId, type, content, toolName, toolInput, toolOutput, isError, createdAt]);
        },
        getSessionMessages(sessionId) {
            const rows = storage.query(`SELECT * FROM session_messages WHERE session_id = ? ORDER BY created_at ASC`, [sessionId]);
            return rows.map(dbToMessage);
        },
        getMessagesForSessions(sessionIds) {
            if (sessionIds.length === 0) {
                return [];
            }
            // Build placeholders for IN clause
            const placeholders = sessionIds.map(() => '?').join(', ');
            const rows = storage.query(`SELECT * FROM session_messages WHERE session_id IN (${placeholders}) ORDER BY created_at ASC`, sessionIds);
            return rows.map(dbToMessage);
        },
        getSessionMessagesAfter(sessionId, afterId) {
            // Get the timestamp of the afterId message, then get all messages after it
            const afterRow = storage.query(`SELECT created_at FROM session_messages WHERE id = ?`, [afterId]);
            if (afterRow.length === 0) {
                // If afterId not found, return all messages
                return this.getSessionMessages(sessionId);
            }
            const rows = storage.query(`SELECT * FROM session_messages
         WHERE session_id = ? AND created_at > ?
         ORDER BY created_at ASC`, [sessionId, afterRow[0].created_at]);
            return rows.map(dbToMessage);
        },
        deleteSessionMessages(sessionId) {
            storage.run(`DELETE FROM session_messages WHERE session_id = ?`, [sessionId]);
        },
        getMessageCount(sessionId) {
            const result = storage.query(`SELECT COUNT(*) as count FROM session_messages WHERE session_id = ?`, [sessionId]);
            return result[0]?.count ?? 0;
        },
        getLatestDisplayableMessage(sessionId) {
            // Get the most recent message that has displayable content:
            // - Has text content, OR
            // - Is a tool_use event (can display tool name), OR
            // - Is a tool_result event (can display "Tool completed")
            // Exclude 'user' type (user prompts are not useful for status display)
            const rows = storage.query(`SELECT * FROM session_messages
         WHERE session_id = ?
           AND type != 'user'
           AND (content IS NOT NULL OR type IN ('tool_use', 'tool_result'))
         ORDER BY created_at DESC
         LIMIT 1`, [sessionId]);
            return rows.length > 0 ? dbToMessage(rows[0]) : undefined;
        },
        getLatestDisplayableMessages(sessionIds) {
            const result = new Map();
            if (sessionIds.length === 0)
                return result;
            // Query each session individually for clarity and to use the index efficiently
            for (const sessionId of sessionIds) {
                const msg = this.getLatestDisplayableMessage(sessionId);
                if (msg) {
                    result.set(sessionId, msg);
                }
            }
            return result;
        },
    };
}
//# sourceMappingURL=session-messages.js.map