import { readKitSqliteUserVersion } from "../../core/state/workspace-kit-sqlite.js";
export const TEAM_EXECUTION_KIT_MIN_USER_VERSION = 7;
const ASSIGNMENT_STATUSES = new Set(["assigned", "submitted", "blocked", "reconciled", "cancelled"]);
export function assertTeamExecutionKitSchema(dbPathAbs) {
    const uv = readKitSqliteUserVersion(dbPathAbs);
    if (uv < TEAM_EXECUTION_KIT_MIN_USER_VERSION) {
        return {
            ok: false,
            message: `team-execution commands require kit SQLite user_version >= ${TEAM_EXECUTION_KIT_MIN_USER_VERSION} (current ${uv}); open the workspace DB once with a current workspace-kit to migrate`
        };
    }
    return { ok: true };
}
export function validateHandoffContractV1(raw) {
    if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
        return { ok: false, message: "handoff must be a JSON object" };
    }
    const o = raw;
    if (o.schemaVersion !== 1) {
        return { ok: false, message: "handoff.schemaVersion must be 1" };
    }
    if (typeof o.summary !== "string" || !o.summary.trim()) {
        return { ok: false, message: "handoff.summary must be a non-empty string" };
    }
    if (o.evidenceRefs !== undefined) {
        if (!Array.isArray(o.evidenceRefs) || !o.evidenceRefs.every((x) => typeof x === "string")) {
            return { ok: false, message: "handoff.evidenceRefs must be an array of strings when present" };
        }
    }
    return { ok: true, json: JSON.stringify(o) };
}
export function validateReconcileCheckpointV1(raw) {
    if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
        return { ok: false, message: "checkpoint must be a JSON object" };
    }
    const o = raw;
    if (o.schemaVersion !== 1) {
        return { ok: false, message: "checkpoint.schemaVersion must be 1" };
    }
    if (typeof o.mergedSummary !== "string" || !o.mergedSummary.trim()) {
        return { ok: false, message: "checkpoint.mergedSummary must be a non-empty string" };
    }
    return { ok: true, json: JSON.stringify(o) };
}
export function parseMetadata(raw) {
    if (raw === undefined || raw === null) {
        return null;
    }
    if (typeof raw !== "object" || Array.isArray(raw)) {
        return null;
    }
    return raw;
}
export function taskExistsInRelationalStore(db, taskId) {
    const row = db
        .prepare("SELECT 1 AS ok FROM task_engine_tasks WHERE id = ? LIMIT 1")
        .get(taskId);
    return Boolean(row);
}
function mapRow(r) {
    let handoff = null;
    if (typeof r.handoff_json === "string" && r.handoff_json.trim()) {
        try {
            const p = JSON.parse(r.handoff_json);
            if (p && typeof p === "object" && !Array.isArray(p)) {
                handoff = p;
            }
        }
        catch {
            handoff = null;
        }
    }
    let reconcileCheckpoint = null;
    if (typeof r.reconcile_checkpoint_json === "string" && r.reconcile_checkpoint_json.trim()) {
        try {
            const p = JSON.parse(r.reconcile_checkpoint_json);
            if (p && typeof p === "object" && !Array.isArray(p)) {
                reconcileCheckpoint = p;
            }
        }
        catch {
            reconcileCheckpoint = null;
        }
    }
    let metadata = null;
    if (typeof r.metadata_json === "string" && r.metadata_json.trim()) {
        try {
            const p = JSON.parse(r.metadata_json);
            if (p && typeof p === "object" && !Array.isArray(p)) {
                metadata = p;
            }
        }
        catch {
            metadata = null;
        }
    }
    const st = String(r.status);
    const status = ASSIGNMENT_STATUSES.has(st) ? st : "assigned";
    return {
        id: String(r.id),
        executionTaskId: String(r.execution_task_id),
        supervisorId: String(r.supervisor_id),
        workerId: String(r.worker_id),
        status,
        handoff,
        reconcileCheckpoint,
        blockReason: typeof r.block_reason === "string" ? r.block_reason : null,
        metadata,
        createdAt: String(r.created_at),
        updatedAt: String(r.updated_at)
    };
}
export function insertAssignment(db, input) {
    const metaStr = input.metadata ? JSON.stringify(input.metadata) : null;
    db.prepare(`INSERT INTO kit_team_assignments (
      id, execution_task_id, supervisor_id, worker_id, status,
      handoff_json, reconcile_checkpoint_json, block_reason, metadata_json, created_at, updated_at
    ) VALUES (?, ?, ?, ?, 'assigned', NULL, NULL, NULL, ?, ?, ?)`).run(input.id, input.executionTaskId, input.supervisorId, input.workerId, metaStr, input.now, input.now);
}
export function getAssignment(db, id) {
    const r = db.prepare("SELECT * FROM kit_team_assignments WHERE id = ?").get(id);
    return r ? mapRow(r) : null;
}
export function listAssignments(db, filter) {
    const clauses = [];
    const params = [];
    if (filter.executionTaskId) {
        clauses.push("execution_task_id = ?");
        params.push(filter.executionTaskId);
    }
    if (filter.status) {
        clauses.push("status = ?");
        params.push(filter.status);
    }
    if (filter.supervisorId) {
        clauses.push("supervisor_id = ?");
        params.push(filter.supervisorId);
    }
    if (filter.workerId) {
        clauses.push("worker_id = ?");
        params.push(filter.workerId);
    }
    const where = clauses.length ? `WHERE ${clauses.join(" AND ")}` : "";
    const rows = db.prepare(`SELECT * FROM kit_team_assignments ${where} ORDER BY created_at ASC`).all(...params);
    return rows.map(mapRow);
}
function emptyTeamDashboardSummary() {
    return {
        schemaVersion: 1,
        available: false,
        totalCount: 0,
        activeCount: 0,
        byStatus: { assigned: 0, submitted: 0, blocked: 0, reconciled: 0, cancelled: 0 },
        topActive: []
    };
}
export function summarizeTeamAssignmentsForNextActions(db, resolveTaskTitle) {
    const empty = {
        schemaVersion: 1,
        available: false,
        openCount: 0,
        topOpen: []
    };
    if (!db) {
        return empty;
    }
    const uvRaw = db.pragma("user_version", { simple: true });
    const uv = typeof uvRaw === "number" ? uvRaw : Number(uvRaw);
    if (!Number.isFinite(uv) || uv < TEAM_EXECUTION_KIT_MIN_USER_VERSION) {
        return empty;
    }
    try {
        const rows = db
            .prepare(`SELECT * FROM kit_team_assignments
         WHERE status IN ('assigned','submitted','blocked')
         ORDER BY updated_at DESC
         LIMIT 25`)
            .all();
        const topOpen = rows.map((raw) => {
            const row = mapRow(raw);
            return {
                assignmentId: row.id,
                executionTaskId: row.executionTaskId,
                executionTaskTitle: resolveTaskTitle(row.executionTaskId),
                supervisorId: row.supervisorId,
                workerId: row.workerId,
                status: row.status,
                updatedAt: row.updatedAt
            };
        });
        const cntRow = db
            .prepare(`SELECT COUNT(*) AS c FROM kit_team_assignments WHERE status IN ('assigned','submitted','blocked')`)
            .get();
        const openCount = cntRow !== undefined ? Number(cntRow.c) || 0 : topOpen.length;
        return {
            schemaVersion: 1,
            available: true,
            openCount,
            topOpen
        };
    }
    catch {
        return empty;
    }
}
export function summarizeTeamAssignmentsForDashboard(db, resolveTaskTitle) {
    const uvRaw = db.pragma("user_version", { simple: true });
    const uv = typeof uvRaw === "number" ? uvRaw : Number(uvRaw);
    if (!Number.isFinite(uv) || uv < TEAM_EXECUTION_KIT_MIN_USER_VERSION) {
        return emptyTeamDashboardSummary();
    }
    try {
        const byStatus = {
            assigned: 0,
            submitted: 0,
            blocked: 0,
            reconciled: 0,
            cancelled: 0
        };
        const countRows = db
            .prepare("SELECT status, COUNT(*) AS c FROM kit_team_assignments GROUP BY status")
            .all();
        let totalCount = 0;
        for (const r of countRows) {
            const c = Number(r.c);
            totalCount += c;
            const st = String(r.status);
            if (st === "assigned") {
                byStatus.assigned = c;
            }
            else if (st === "submitted") {
                byStatus.submitted = c;
            }
            else if (st === "blocked") {
                byStatus.blocked = c;
            }
            else if (st === "reconciled") {
                byStatus.reconciled = c;
            }
            else if (st === "cancelled") {
                byStatus.cancelled = c;
            }
        }
        const activeCount = byStatus.assigned + byStatus.submitted + byStatus.blocked;
        const topRows = db
            .prepare(`SELECT * FROM kit_team_assignments
         WHERE status IN ('assigned','submitted','blocked')
         ORDER BY updated_at DESC
         LIMIT 15`)
            .all();
        const topActive = topRows.map((raw) => {
            const row = mapRow(raw);
            return {
                id: row.id,
                executionTaskId: row.executionTaskId,
                executionTaskTitle: resolveTaskTitle(row.executionTaskId),
                supervisorId: row.supervisorId,
                workerId: row.workerId,
                status: row.status,
                updatedAt: row.updatedAt
            };
        });
        return {
            schemaVersion: 1,
            available: true,
            totalCount,
            activeCount,
            byStatus,
            topActive
        };
    }
    catch {
        return emptyTeamDashboardSummary();
    }
}
export function submitHandoff(db, input) {
    const r = db
        .prepare(`UPDATE kit_team_assignments SET status = 'submitted', handoff_json = ?, block_reason = NULL, updated_at = ?
       WHERE id = ? AND worker_id = ? AND status = 'assigned'`)
        .run(input.handoffJson, input.now, input.assignmentId, input.workerId);
    return r.changes > 0;
}
export function blockAssignment(db, input) {
    const r = db
        .prepare(`UPDATE kit_team_assignments SET status = 'blocked', block_reason = ?, updated_at = ?
       WHERE id = ? AND supervisor_id = ? AND status IN ('assigned','submitted')`)
        .run(input.reason, input.now, input.assignmentId, input.supervisorId);
    return r.changes > 0;
}
export function reconcileAssignment(db, input) {
    const r = db
        .prepare(`UPDATE kit_team_assignments SET status = 'reconciled', reconcile_checkpoint_json = ?, updated_at = ?
       WHERE id = ? AND supervisor_id = ? AND status = 'submitted'`)
        .run(input.checkpointJson, input.now, input.assignmentId, input.supervisorId);
    return r.changes > 0;
}
export function cancelAssignment(db, input) {
    const r = db
        .prepare(`UPDATE kit_team_assignments SET status = 'cancelled', updated_at = ?
       WHERE id = ? AND supervisor_id = ? AND status IN ('assigned','submitted','blocked')`)
        .run(input.now, input.assignmentId, input.supervisorId);
    return r.changes > 0;
}
