import { getConnection } from '../../../modules/database/connection.js';
import { projectsDb } from '../../../modules/database/repositories/projects.db.js';
import { normalizeProjectPath } from '../../../shared/utils.js';
function normalizeTimestamp(value) {
    if (!value)
        return null;
    const parsed = new Date(value);
    if (Number.isNaN(parsed.getTime())) {
        return null;
    }
    return parsed.toISOString();
}
function normalizeProjectPathForProvider(provider, projectPath) {
    void provider;
    return normalizeProjectPath(projectPath);
}
export const sessionsDb = {
    createSession(userId, sessionId, provider, projectPath, customName, createdAt, updatedAt, jsonlPath) {
        const db = getConnection();
        const createdAtValue = normalizeTimestamp(createdAt);
        const updatedAtValue = normalizeTimestamp(updatedAt);
        const normalizedProjectPath = normalizeProjectPathForProvider(provider, projectPath);
        // First, ensure the project path is recorded in the projects table,
        // since it's a foreign key in the sessions table.
        projectsDb.createProjectPath(userId, normalizedProjectPath);
        db.prepare(`INSERT INTO sessions (session_id, user_id, provider, custom_name, project_path, jsonl_path, isArchived, created_at, updated_at)
       VALUES (?, ?, ?, ?, ?, ?, 0, COALESCE(?, CURRENT_TIMESTAMP), COALESCE(?, CURRENT_TIMESTAMP))
       ON CONFLICT(user_id, session_id) DO UPDATE SET
         provider = excluded.provider,
         updated_at = excluded.updated_at,
         project_path = excluded.project_path,
         jsonl_path = excluded.jsonl_path,
         isArchived = 0,
         custom_name = COALESCE(excluded.custom_name, sessions.custom_name)`).run(sessionId, userId, provider, customName ?? null, normalizedProjectPath, jsonlPath ?? null, createdAtValue, updatedAtValue);
        return sessionId;
    },
    updateSessionCustomName(userId, sessionId, customName) {
        const db = getConnection();
        db.prepare(`UPDATE sessions
       SET custom_name = ?
       WHERE user_id = ? AND session_id = ?`).run(customName, userId, sessionId);
    },
    getSessionById(userId, sessionId) {
        const db = getConnection();
        const row = db
            .prepare(`SELECT session_id, user_id, provider, project_path, jsonl_path, custom_name, isArchived, created_at, updated_at
         FROM sessions
         WHERE user_id = ? AND session_id = ?
         ORDER BY updated_at DESC
         LIMIT 1`)
            .get(userId, sessionId);
        return row ?? null;
    },
    getAllSessions(userId) {
        const db = getConnection();
        return db
            .prepare(`SELECT session_id, user_id, provider, project_path, jsonl_path, custom_name, isArchived, created_at, updated_at
         FROM sessions
         WHERE user_id = ? AND isArchived = 0`)
            .all(userId);
    },
    /**
     * Archived rows are intentionally queried separately so the caller can render
     * them in a dedicated view without reintroducing them into active session lists.
     */
    getArchivedSessions(userId) {
        const db = getConnection();
        return db
            .prepare(`SELECT session_id, user_id, provider, project_path, jsonl_path, custom_name, isArchived, created_at, updated_at
         FROM sessions
         WHERE user_id = ? AND isArchived = 1
         ORDER BY datetime(COALESCE(updated_at, created_at)) DESC, session_id DESC`)
            .all(userId);
    },
    getSessionsByProjectPath(userId, projectPath) {
        const db = getConnection();
        const normalizedProjectPath = normalizeProjectPath(projectPath);
        return db
            .prepare(`SELECT session_id, user_id, provider, project_path, jsonl_path, custom_name, isArchived, created_at, updated_at
         FROM sessions
         WHERE user_id = ? AND project_path = ?
           AND isArchived = 0`)
            .all(userId, normalizedProjectPath);
    },
    /**
     * Permanent project deletion must see every session row for the path,
     * including archived ones, so their transcript files can be cleaned up.
     */
    getSessionsByProjectPathIncludingArchived(userId, projectPath) {
        const db = getConnection();
        const normalizedProjectPath = normalizeProjectPath(projectPath);
        return db
            .prepare(`SELECT session_id, user_id, provider, project_path, jsonl_path, custom_name, isArchived, created_at, updated_at
         FROM sessions
         WHERE user_id = ? AND project_path = ?`)
            .all(userId, normalizedProjectPath);
    },
    getSessionsByProjectPathPage(userId, projectPath, limit, offset) {
        const db = getConnection();
        const normalizedProjectPath = normalizeProjectPath(projectPath);
        return db
            .prepare(`SELECT session_id, user_id, provider, project_path, jsonl_path, custom_name, isArchived, created_at, updated_at
         FROM sessions
         WHERE user_id = ? AND project_path = ?
           AND isArchived = 0
         ORDER BY datetime(COALESCE(updated_at, created_at)) DESC, session_id DESC
         LIMIT ? OFFSET ?`)
            .all(userId, normalizedProjectPath, limit, offset);
    },
    countSessionsByProjectPath(userId, projectPath) {
        const db = getConnection();
        const normalizedProjectPath = normalizeProjectPath(projectPath);
        const row = db
            .prepare(`SELECT COUNT(*) AS count
         FROM sessions
         WHERE user_id = ? AND project_path = ?
           AND isArchived = 0`)
            .get(userId, normalizedProjectPath);
        return Number(row?.count ?? 0);
    },
    deleteSessionsByProjectPath(userId, projectPath) {
        const db = getConnection();
        const normalizedProjectPath = normalizeProjectPath(projectPath);
        db.prepare(`DELETE FROM sessions WHERE user_id = ? AND project_path = ?`).run(userId, normalizedProjectPath);
    },
    getSessionName(userId, sessionId, provider) {
        const db = getConnection();
        const row = db
            .prepare(`SELECT custom_name
         FROM sessions
         WHERE user_id = ? AND session_id = ? AND provider = ?`)
            .get(userId, sessionId, provider);
        return row?.custom_name ?? null;
    },
    /**
     * Soft-delete and restore both use the same flag update so callers keep the
     * row, metadata, and file path intact while toggling visibility.
     */
    updateSessionIsArchived(userId, sessionId, isArchived) {
        const db = getConnection();
        db.prepare(`UPDATE sessions
       SET isArchived = ?
       WHERE user_id = ? AND session_id = ?`).run(isArchived ? 1 : 0, userId, sessionId);
    },
    deleteSessionById(userId, sessionId) {
        const db = getConnection();
        return (db.prepare('DELETE FROM sessions WHERE user_id = ? AND session_id = ?').run(userId, sessionId).changes > 0);
    },
};
//# sourceMappingURL=sessions.db.js.map