"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createEscalation = createEscalation;
exports.claimEscalation = claimEscalation;
exports.resolveEscalation = resolveEscalation;
exports.updateEscalationsPriority = updateEscalationsPriority;
exports.getEscalationRoles = getEscalationRoles;
exports.releaseEscalation = releaseEscalation;
exports.releaseExpiredClaims = releaseExpiredClaims;
exports.escalateToRole = escalateToRole;
exports.getEscalation = getEscalation;
exports.getEscalationsByTaskId = getEscalationsByTaskId;
exports.getEscalationsByWorkflowId = getEscalationsByWorkflowId;
exports.updateEscalationMetadata = updateEscalationMetadata;
exports.enrichEscalationRouting = enrichEscalationRouting;
exports.getEscalationsByOriginId = getEscalationsByOriginId;
const db_1 = require("../../lib/db");
const sql_1 = require("./sql");
async function createEscalation(input) {
    const pool = (0, db_1.getPool)();
    // Ensure the role exists in lt_roles (FK constraint)
    await pool.query(sql_1.ENSURE_ROLE_EXISTS, [input.role]);
    const { rows } = await pool.query(sql_1.CREATE_ESCALATION, [
        input.type,
        input.subtype,
        input.description || null,
        input.priority || 2,
        input.task_id || null,
        input.origin_id || null,
        input.parent_id || null,
        input.role,
        input.envelope,
        input.metadata ? JSON.stringify(input.metadata) : null,
        input.escalation_payload || null,
        input.workflow_id || null,
        input.task_queue || null,
        input.workflow_type || null,
        input.trace_id || null,
        input.span_id || null,
    ]);
    return rows[0];
}
/**
 * Atomic claim operation. Does NOT change status — "claimed" is implicit
 * via assigned_to + assigned_until > NOW().
 *
 * Conditions:
 * - status = 'pending' (not resolved/cancelled)
 * - Either: unassigned, expired claim, or same user (extension)
 *
 * Uses a CTE to capture the previous state so callers can detect extensions.
 */
async function claimEscalation(id, userId, durationMinutes = 30) {
    const pool = (0, db_1.getPool)();
    const { rows } = await pool.query(sql_1.CLAIM_ESCALATION, [id, userId, durationMinutes]);
    if (rows.length === 0)
        return null;
    const row = rows[0];
    return {
        escalation: row,
        isExtension: row.prev_assigned_to === userId,
    };
}
async function resolveEscalation(id, resolverPayload) {
    const pool = (0, db_1.getPool)();
    const { rows } = await pool.query(sql_1.RESOLVE_ESCALATION, [id, JSON.stringify(resolverPayload)]);
    return rows[0] || null;
}
/**
 * Bulk update priority for a set of escalations.
 * Only updates pending escalations.
 */
async function updateEscalationsPriority(ids, priority) {
    if (ids.length === 0)
        return 0;
    const pool = (0, db_1.getPool)();
    const { rowCount } = await pool.query(sql_1.UPDATE_ESCALATIONS_PRIORITY, [priority, ids]);
    return rowCount ?? 0;
}
/**
 * Get the distinct roles for a set of escalation IDs.
 * Used for permission validation before bulk operations.
 */
async function getEscalationRoles(ids) {
    if (ids.length === 0)
        return [];
    const pool = (0, db_1.getPool)();
    const { rows } = await pool.query(sql_1.GET_ESCALATION_ROLES, [ids]);
    return rows.map((r) => r.role);
}
/**
 * Release a single escalation claim back to the available pool.
 * Only the assigned user (or superadmin via route) may release.
 */
async function releaseEscalation(id, userId) {
    const pool = (0, db_1.getPool)();
    const { rows } = await pool.query(sql_1.RELEASE_ESCALATION, [id, userId]);
    return rows[0] || null;
}
async function releaseExpiredClaims() {
    const pool = (0, db_1.getPool)();
    const { rowCount } = await pool.query(sql_1.RELEASE_EXPIRED_CLAIMS);
    return rowCount || 0;
}
/**
 * Reassign an escalation to a different role.
 * Clears the current assignment so it becomes available to the new role.
 */
async function escalateToRole(id, targetRole) {
    const pool = (0, db_1.getPool)();
    const { rows } = await pool.query(sql_1.ESCALATE_TO_ROLE, [id, targetRole]);
    return rows[0] || null;
}
async function getEscalation(id) {
    const pool = (0, db_1.getPool)();
    const { rows } = await pool.query(sql_1.GET_ESCALATION, [id]);
    return rows[0] || null;
}
async function getEscalationsByTaskId(taskId) {
    const pool = (0, db_1.getPool)();
    const { rows } = await pool.query(sql_1.GET_ESCALATIONS_BY_TASK_ID, [taskId]);
    return rows;
}
async function getEscalationsByWorkflowId(workflowId) {
    const pool = (0, db_1.getPool)();
    const { rows } = await pool.query(sql_1.GET_ESCALATIONS_BY_WORKFLOW_ID, [workflowId]);
    return rows;
}
async function updateEscalationMetadata(id, patch) {
    const pool = (0, db_1.getPool)();
    const { rows } = await pool.query(sql_1.UPDATE_ESCALATION_METADATA, [id, JSON.stringify(patch)]);
    return rows[0] || null;
}
async function enrichEscalationRouting(id, metadataPatch, workflowFields) {
    const pool = (0, db_1.getPool)();
    const { rows } = await pool.query(sql_1.ENRICH_ESCALATION_ROUTING, [
        id,
        JSON.stringify(metadataPatch),
        workflowFields.workflowType || null,
        workflowFields.workflowId || null,
        workflowFields.taskQueue || null,
        workflowFields.taskId || null,
    ]);
    return rows[0] || null;
}
async function getEscalationsByOriginId(originId) {
    const pool = (0, db_1.getPool)();
    const { rows } = await pool.query(sql_1.GET_ESCALATIONS_BY_ORIGIN_ID, [originId]);
    return rows;
}
