"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.hasActiveScheduledRun = hasActiveScheduledRun;
exports.isScheduledRunDue = isScheduledRunDue;
exports.isCooldownScheduledRunState = isCooldownScheduledRunState;
exports.isCooldownScheduledRun = isCooldownScheduledRun;
exports.resolveCooldownScheduledRunReason = resolveCooldownScheduledRunReason;
exports.createCooldownScheduledRun = createCooldownScheduledRun;
exports.materializeScheduledRunCommand = materializeScheduledRunCommand;
exports.resolveScheduledRunProjection = resolveScheduledRunProjection;
exports.clearScheduledRun = clearScheduledRun;
const types_1 = require("../platform/workflow-state/types");
const schedule_primitives_1 = require("./schedule-primitives");
function hasActiveScheduledRun(workflowState) {
    return workflowState?.scheduledRun?.kind === "one_shot";
}
function isScheduledRunDue(workflowState, now = new Date()) {
    return hasActiveScheduledRun(workflowState)
        ? (0, schedule_primitives_1.isDueAt)(workflowState.scheduledRun.runAt, now)
        : false;
}
function isCooldownScheduledRunState(scheduledRun) {
    return (scheduledRun?.kind === "one_shot" &&
        scheduledRun.requestedBy === "cooldown" &&
        resolveCooldownScheduledRunReason(scheduledRun) !== null);
}
function isCooldownScheduledRun(workflowState) {
    return isCooldownScheduledRunState(workflowState?.scheduledRun);
}
function resolveCooldownScheduledRunReason(scheduledRun) {
    if (scheduledRun?.requestedBy !== "cooldown") {
        return null;
    }
    return scheduledRun.requestedValue === "quota_exhausted" ||
        scheduledRun.requestedValue === "capacity"
        ? scheduledRun.requestedValue
        : null;
}
function createCooldownScheduledRun(input) {
    const runAtMs = Date.parse(input.runAt);
    const requestedAtMs = Date.parse(input.requestedAt ?? new Date().toISOString());
    if (!Number.isFinite(runAtMs) || !Number.isFinite(requestedAtMs)) {
        return null;
    }
    return {
        kind: "one_shot",
        runAt: new Date(runAtMs).toISOString(),
        requestedAt: new Date(requestedAtMs).toISOString(),
        requestedBy: "cooldown",
        requestedValue: input.reason,
    };
}
function materializeScheduledRunCommand(input) {
    if (input.command.mode === "off") {
        return null;
    }
    const runAt = input.command.mode === "run_after"
        ? (0, schedule_primitives_1.resolveWorkflowRunAfter)(input.command.value, input.acceptedAt)
        : (0, schedule_primitives_1.normalizeWorkflowRunAt)(input.command.value, input.displayTimeZone);
    if (runAt === null) {
        return null;
    }
    const runAtMs = Date.parse(runAt);
    const acceptedAtMs = Date.parse(input.acceptedAt);
    if (!Number.isFinite(runAtMs) || !Number.isFinite(acceptedAtMs)) {
        return null;
    }
    if (runAtMs <= acceptedAtMs) {
        return null;
    }
    return {
        kind: "one_shot",
        runAt,
        requestedAt: new Date(acceptedAtMs).toISOString(),
        requestedBy: input.command.mode,
        requestedValue: input.command.value,
    };
}
function resolveScheduledRunProjection(input) {
    if (!hasActiveScheduledRun(input.workflowState)) {
        return {
            snapshot: input.snapshot,
        };
    }
    if (input.snapshot.status === types_1.WORKFLOW_STATUSES.aiNeedsHuman) {
        return {
            snapshot: input.snapshot,
        };
    }
    if (input.snapshot.rules.includes(types_1.WORKFLOW_RULES.aiDisabled)) {
        return {
            snapshot: {
                status: types_1.WORKFLOW_STATUSES.aiScheduled,
                rules: [...input.snapshot.rules],
            },
        };
    }
    if (!isScheduledRunDue(input.workflowState)) {
        return {
            snapshot: {
                status: types_1.WORKFLOW_STATUSES.aiScheduled,
                rules: input.snapshot.rules.filter((rule) => rule !== types_1.WORKFLOW_RULES.aiDisabled),
            },
        };
    }
    return {
        snapshot: {
            status: types_1.WORKFLOW_STATUSES.aiReady,
            rules: input.snapshot.rules.filter((rule) => rule !== types_1.WORKFLOW_RULES.aiDisabled),
        },
    };
}
function clearScheduledRun(workflowState) {
    const { scheduledRun: _scheduledRun, ...nextWorkflowState } = workflowState;
    return nextWorkflowState;
}
