"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.releaseExpiredClaims = releaseExpiredClaims;
exports.updatePriority = updatePriority;
exports.bulkClaim = bulkClaim;
exports.bulkAssign = bulkAssign;
exports.bulkEscalate = bulkEscalate;
exports.bulkTriage = bulkTriage;
const escalationService = __importStar(require("../../services/escalation"));
const userService = __importStar(require("../../services/user"));
const taskService = __importStar(require("../../services/task"));
const workers_1 = require("../../workers");
const defaults_1 = require("../../modules/defaults");
const helpers_1 = require("./helpers");
// ── Bulk routes ────────────────────────────────────────────────────────────
/**
 * Release all escalation claims past their `assigned_until` deadline.
 *
 * Typically called on a maintenance schedule. Returns the count of
 * released claims.
 *
 * @returns `{ status: 200, data: { released: number } }`
 */
async function releaseExpiredClaims() {
    try {
        const released = await escalationService.releaseExpiredClaims();
        return { status: 200, data: { released } };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * Update priority for one or more escalations.
 *
 * @param input.ids — array of escalation UUIDs
 * @param input.priority — new priority (1=critical, 2=high, 3=medium, 4=low)
 * @param auth — authenticated user context (admin or role-holder required)
 * @returns `{ status: 200, data: { updated: number } }`
 */
async function updatePriority(input, auth) {
    try {
        const { ids, priority } = input;
        if (!(0, helpers_1.validateIds)(ids)) {
            return { status: 400, error: 'ids must be a non-empty array' };
        }
        if (![1, 2, 3, 4].includes(priority)) {
            return { status: 400, error: 'priority must be 1, 2, 3, or 4' };
        }
        const perm = await (0, helpers_1.checkBulkPermission)(auth.userId, ids);
        if (!perm.allowed)
            return perm;
        const updated = await escalationService.updateEscalationsPriority(ids, priority);
        return { status: 200, data: { updated } };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * Claim multiple escalations at once for the authenticated user.
 *
 * @param input.ids — array of escalation UUIDs
 * @param input.durationMinutes — claim duration (default: 30)
 * @param auth — authenticated user context
 * @returns `{ status: 200, data: { claimed, skipped } }`
 */
async function bulkClaim(input, auth) {
    try {
        const { ids, durationMinutes } = input;
        if (!(0, helpers_1.validateIds)(ids)) {
            return { status: 400, error: 'ids must be a non-empty array' };
        }
        const perm = await (0, helpers_1.checkBulkPermission)(auth.userId, ids);
        if (!perm.allowed)
            return perm;
        const result = await escalationService.bulkClaimEscalations(ids, auth.userId, durationMinutes ?? 30);
        if (result.claimed > 0)
            (0, helpers_1.publishBulkClaimEvents)(ids, auth.userId);
        return { status: 200, data: result };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * Assign multiple escalations to a specific user.
 *
 * Non-superadmin callers must verify the target user holds each
 * escalation's role. Publishes claim events for assigned items.
 *
 * @param input.ids — array of escalation UUIDs
 * @param input.targetUserId — user to assign to
 * @param input.durationMinutes — assignment duration (default: 30)
 * @param auth — authenticated user context
 * @returns `{ status: 200, data: { assigned, skipped } }`
 */
async function bulkAssign(input, auth) {
    try {
        const { ids, targetUserId, durationMinutes } = input;
        if (!(0, helpers_1.validateIds)(ids)) {
            return { status: 400, error: 'ids must be a non-empty array' };
        }
        if (!targetUserId || typeof targetUserId !== 'string') {
            return { status: 400, error: 'targetUserId is required' };
        }
        const perm = await (0, helpers_1.checkBulkPermission)(auth.userId, ids);
        if (!perm.allowed)
            return perm;
        // Non-superadmin: target user must hold each escalation's role
        const isSuperAdminUser = await userService.isSuperAdmin(auth.userId);
        if (!isSuperAdminUser) {
            const roles = await escalationService.getEscalationRoles(ids);
            for (const role of roles) {
                const targetHasRole = await userService.hasRole(targetUserId, role);
                if (!targetHasRole) {
                    return { status: 400, error: `Target user does not hold the "${role}" role` };
                }
            }
        }
        const result = await escalationService.bulkAssignEscalations(ids, targetUserId, durationMinutes ?? 30);
        if (result.assigned > 0)
            (0, helpers_1.publishBulkClaimEvents)(ids, targetUserId);
        return { status: 200, data: result };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * Route multiple escalations to a different role.
 *
 * @param input.ids — array of escalation UUIDs
 * @param input.targetRole — destination role
 * @param auth — authenticated user context
 * @returns `{ status: 200, data: { updated: number } }`
 */
async function bulkEscalate(input, auth) {
    try {
        const { ids, targetRole } = input;
        if (!(0, helpers_1.validateIds)(ids)) {
            return { status: 400, error: 'ids must be a non-empty array' };
        }
        if (!targetRole || typeof targetRole !== 'string') {
            return { status: 400, error: 'targetRole is required' };
        }
        const perm = await (0, helpers_1.checkBulkPermission)(auth.userId, ids);
        if (!perm.allowed)
            return perm;
        const updated = await escalationService.bulkEscalateToRole(ids, targetRole);
        return { status: 200, data: { updated } };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
/**
 * Trigger AI triage for multiple escalations.
 *
 * Resolves each escalation and starts a triage workflow that uses MCP
 * tools to analyze and potentially auto-resolve the issue.
 *
 * @param input.ids — array of escalation UUIDs
 * @param input.hint — optional natural-language guidance for the triage AI
 * @param auth — authenticated user context
 * @returns `{ status: 200, data: { triaged, workflows } }`
 */
async function bulkTriage(input, auth) {
    try {
        const { ids, hint } = input;
        if (!(0, helpers_1.validateIds)(ids)) {
            return { status: 400, error: 'ids must be a non-empty array' };
        }
        const perm = await (0, helpers_1.checkBulkPermission)(auth.userId, ids);
        if (!perm.allowed)
            return perm;
        const resolved = await escalationService.bulkResolveForTriage(ids, hint);
        const client = (0, workers_1.createClient)();
        const workflowIds = [];
        for (const escalation of resolved) {
            const triageWorkflowId = await startTriageWorkflow(escalation, hint, auth.userId, client);
            workflowIds.push(triageWorkflowId);
        }
        return { status: 200, data: { triaged: resolved.length, workflows: workflowIds } };
    }
    catch (err) {
        return { status: 500, error: err.message };
    }
}
// ── Triage workflow launcher (shared by bulkTriage) ────────────────────────
async function startTriageWorkflow(escalation, hint, userId, client) {
    let escalationPayload = {};
    if (escalation.escalation_payload) {
        try {
            escalationPayload = JSON.parse(escalation.escalation_payload);
        }
        catch { }
    }
    let envelope = {};
    if (escalation.envelope) {
        try {
            envelope = JSON.parse(escalation.envelope);
        }
        catch { }
    }
    const triageWorkflowId = `triage-${escalation.id}-${Date.now()}`;
    const triageEnvelope = {
        data: {
            escalationId: escalation.id,
            originId: escalation.origin_id ?? undefined,
            originalWorkflowType: escalation.workflow_type,
            originalTaskQueue: escalation.task_queue,
            originalTaskId: escalation.task_id,
            escalationPayload,
            resolverPayload: {
                _lt: { needsTriage: true, ...(hint ? { hint } : {}) },
            },
        },
        metadata: envelope.metadata || {},
        lt: { ...(envelope.lt || {}), userId },
    };
    const routing = escalation.task_id
        ? (await taskService.getTask(escalation.task_id))?.metadata
        : null;
    await taskService.createTask({
        workflow_id: triageWorkflowId,
        workflow_type: 'mcpTriage',
        lt_type: 'mcpTriage',
        task_queue: 'long-tail-system',
        signal_id: `lt-triage-${triageWorkflowId}`,
        parent_workflow_id: routing?.parentWorkflowId || triageWorkflowId,
        origin_id: escalation.origin_id || triageWorkflowId,
        parent_id: escalation.parent_id ?? undefined,
        envelope: JSON.stringify(triageEnvelope),
        metadata: routing || undefined,
    });
    await client.workflow.start({
        workflowName: 'mcpTriage',
        args: [triageEnvelope],
        taskQueue: 'long-tail-system',
        workflowId: triageWorkflowId,
        expire: defaults_1.JOB_EXPIRE_SECS,
        entity: 'mcpTriage',
    });
    return triageWorkflowId;
}
