import fs from "node:fs";
import path from "node:path";
import { createRequire } from "node:module";
import { throwNativeSqliteLoadError } from "../native-sqlite-diagnostics.js";
import { prepareKitSqliteDatabase } from "./kit-sqlite/planning-sqlite-kernel.js";
const requireBetterSqlite3 = createRequire(import.meta.url);
function loadBetterSqlite3Constructor() {
    try {
        return requireBetterSqlite3("better-sqlite3");
    }
    catch (error) {
        throwNativeSqliteLoadError(error);
    }
}
import { syncWorkspaceKitStatusFromYamlIfNeeded } from "../../modules/task-engine/persistence/workspace-status-yaml-import.js";
export class UnifiedStateDb {
    db = null;
    dbPath;
    exportSnapshotPath;
    workspaceRoot;
    constructor(workspacePath, databaseRelativePath, options) {
        this.workspaceRoot = workspacePath;
        this.dbPath = path.resolve(workspacePath, databaseRelativePath);
        this.exportSnapshotPath = options?.exportSnapshotRelativePath
            ? path.resolve(workspacePath, options.exportSnapshotRelativePath)
            : null;
    }
    ensureDb() {
        if (this.db)
            return this.db;
        fs.mkdirSync(path.dirname(this.dbPath), { recursive: true });
        const DatabaseCtor = loadBetterSqlite3Constructor();
        this.db = new DatabaseCtor(this.dbPath);
        prepareKitSqliteDatabase(this.db);
        syncWorkspaceKitStatusFromYamlIfNeeded(this.workspaceRoot, this.db);
        return this.db;
    }
    getModuleState(moduleId) {
        const db = this.ensureDb();
        const row = db
            .prepare("SELECT module_id, state_schema_version, state_json, updated_at FROM workspace_module_state WHERE module_id = ?")
            .get(moduleId);
        if (!row)
            return null;
        return {
            moduleId: row.module_id,
            stateSchemaVersion: row.state_schema_version,
            state: JSON.parse(row.state_json),
            updatedAt: row.updated_at
        };
    }
    setModuleState(moduleId, stateSchemaVersion, state) {
        const db = this.ensureDb();
        const updatedAt = new Date().toISOString();
        db.prepare(`INSERT INTO workspace_module_state (module_id, state_schema_version, state_json, updated_at)
       VALUES (?, ?, ?, ?)
       ON CONFLICT(module_id) DO UPDATE SET
         state_schema_version=excluded.state_schema_version,
         state_json=excluded.state_json,
         updated_at=excluded.updated_at`).run(moduleId, stateSchemaVersion, JSON.stringify(state), updatedAt);
        this.maybeExportSnapshot();
    }
    deleteModuleState(moduleId) {
        const db = this.ensureDb();
        db.prepare("DELETE FROM workspace_module_state WHERE module_id = ?").run(moduleId);
        this.maybeExportSnapshot();
    }
    listModuleStates() {
        const db = this.ensureDb();
        const rows = db
            .prepare("SELECT module_id, state_schema_version, state_json, updated_at FROM workspace_module_state ORDER BY module_id ASC")
            .all();
        return rows.map((row) => ({
            moduleId: row.module_id,
            stateSchemaVersion: row.state_schema_version,
            state: JSON.parse(row.state_json),
            updatedAt: row.updated_at
        }));
    }
    maybeExportSnapshot() {
        if (!this.exportSnapshotPath)
            return;
        const snapshot = {
            schemaVersion: 1,
            exportedAt: new Date().toISOString(),
            dbPath: this.dbPath,
            modules: this.listModuleStates()
        };
        fs.mkdirSync(path.dirname(this.exportSnapshotPath), { recursive: true });
        fs.writeFileSync(this.exportSnapshotPath, JSON.stringify(snapshot, null, 2) + "\n", "utf8");
    }
}
