"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleEscalation = handleEscalation;
exports.handleErrorEscalation = handleErrorEscalation;
const state_1 = require("./state");
const publish_1 = require("../../lib/events/publish");
const credentials_1 = require("../iam/credentials");
/**
 * Handle a workflow that returned { type: 'escalation' }.
 *
 * Creates an escalation record with full routing context so the
 * work can be resolved by a person or another AI — and the workflow
 * resumes exactly where it left off.
 *
 * Task lifecycle is the orchestrator's responsibility. The interceptor
 * only creates and resolves escalations linked to the parent task.
 *
 * The workflow ENDS here. Resolution starts a new workflow.
 */
async function handleEscalation(state, result) {
    const { activities, wfConfig, defaultRole } = state;
    const storedEnvelope = (0, state_1.buildStoredEnvelope)(state);
    // Mark the task as needing intervention
    if (state.taskId) {
        await activities.ltEscalateTask(state.taskId);
    }
    const escalationId = await activities.ltCreateEscalation({
        type: state.workflowName,
        subtype: state.workflowName,
        description: result.message,
        priority: result.priority,
        taskId: state.taskId,
        originId: state.envelope?.lt?.originId,
        parentId: state.envelope?.lt?.parentId,
        role: result.role || wfConfig?.role || defaultRole,
        envelope: JSON.stringify(storedEnvelope),
        escalationPayload: JSON.stringify(result.data),
        workflowId: state.workflowId,
        taskQueue: state.taskQueue,
        workflowType: state.workflowName,
        traceId: state.traceId,
        spanId: state.spanId,
    });
    (0, publish_1.publishEscalationEvent)({
        type: 'escalation.created',
        source: 'interceptor',
        workflowId: state.workflowId,
        workflowName: state.workflowName,
        taskQueue: state.taskQueue,
        taskId: state.taskId,
        escalationId,
        originId: state.envelope?.lt?.originId,
        status: 'pending',
        data: result.data,
    });
    (0, publish_1.publishTaskEvent)({
        type: 'task.escalated',
        source: 'interceptor',
        workflowId: state.workflowId,
        workflowName: state.workflowName,
        taskQueue: state.taskQueue,
        taskId: state.taskId,
        originId: state.envelope?.lt?.originId,
        status: 'needs_intervention',
    });
    return result;
}
/**
 * Handle an unhandled error by converting it to an escalation.
 *
 * Same flow as handleEscalation, but constructs the LTEscalation
 * from the error — capturing the message and stack trace so the
 * resolver has full context.
 *
 * For MissingCredentialError, produces a categorized escalation with
 * `category: 'missing_credential'` so the UI can render actionable guidance.
 */
async function handleErrorEscalation(state, err) {
    const { activities, wfConfig, defaultRole } = state;
    const isMissingCred = err instanceof credentials_1.MissingCredentialError || err.name === 'MissingCredentialError';
    const storedEnvelope = (0, state_1.buildStoredEnvelope)(state);
    // Mark the task as needing intervention
    if (state.taskId) {
        await activities.ltEscalateTask(state.taskId);
    }
    const escalationPayload = isMissingCred
        ? {
            category: 'missing_credential',
            provider: err.provider,
            error: err.message,
        }
        : { error: err.message, stack: err.stack };
    const description = isMissingCred
        ? `Missing credential: ${err.provider}. Register one at Credentials and retry.`
        : `Unhandled error: ${err.message || String(err)}`;
    const errorEscalationId = await activities.ltCreateEscalation({
        type: state.workflowName,
        subtype: isMissingCred ? 'missing_credential' : state.workflowName,
        description,
        taskId: state.taskId,
        originId: state.envelope?.lt?.originId,
        parentId: state.envelope?.lt?.parentId,
        role: wfConfig?.role || defaultRole,
        envelope: JSON.stringify(storedEnvelope),
        escalationPayload: JSON.stringify(escalationPayload),
        workflowId: state.workflowId,
        taskQueue: state.taskQueue,
        workflowType: state.workflowName,
        traceId: state.traceId,
        spanId: state.spanId,
    });
    (0, publish_1.publishEscalationEvent)({
        type: 'escalation.created',
        source: 'interceptor',
        workflowId: state.workflowId,
        workflowName: state.workflowName,
        taskQueue: state.taskQueue,
        taskId: state.taskId,
        escalationId: errorEscalationId,
        originId: state.envelope?.lt?.originId,
        status: 'pending',
        data: { error: err.message },
    });
    (0, publish_1.publishTaskEvent)({
        type: 'task.escalated',
        source: 'interceptor',
        workflowId: state.workflowId,
        workflowName: state.workflowName,
        taskQueue: state.taskQueue,
        taskId: state.taskId,
        originId: state.envelope?.lt?.originId,
        status: 'needs_intervention',
    });
    (0, publish_1.publishWorkflowEvent)({
        type: 'workflow.failed',
        source: 'interceptor',
        workflowId: state.workflowId,
        workflowName: state.workflowName,
        taskQueue: state.taskQueue,
        taskId: state.taskId,
        originId: state.envelope?.lt?.originId,
        status: 'failed',
        data: { error: err.message },
    });
    return {
        type: 'escalation',
        data: escalationPayload,
        message: description,
    };
}
