"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NEXT_ACTION_RESOLVER_VERSION = void 0;
exports.resolveNextAction = resolveNextAction;
exports.NEXT_ACTION_RESOLVER_VERSION = 1;
const ACTION_ORDER = [
    "repair_state",
    "none",
    "supersede_attempt",
    "recover_contract_revision",
    "recertify_plan",
    "resolve_blocker",
    "refine_task",
    "revise",
    "implement",
    "address_validation",
    "review",
    "close",
    "reconcile"
];
function resolveNextAction(input) {
    const invalidStateFindings = normalizeFindings(input.invalidStateFindings ?? []);
    const activeBlockers = normalizeFindings(input.activeBlockers ?? []);
    const validationFindings = normalizeFindings(input.validationFindings ?? []);
    const primary = firstMatch(input, invalidStateFindings, activeBlockers, validationFindings);
    return {
        nextAction: primary.nextAction,
        reasonCode: primary.reasonCode,
        blockingFindings: primary.findings,
        alternatives: normalizeAlternatives(input.alternativeCandidates ?? [], primary.blocking),
        resolverVersion: exports.NEXT_ACTION_RESOLVER_VERSION
    };
}
function firstMatch(input, invalidStateFindings, activeBlockers, validationFindings) {
    if (invalidStateFindings.length > 0) {
        return match("repair_state", "invalid_state", true, invalidStateFindings);
    }
    if (input.taskStatus === "cancelled" || input.taskStatus === "completed") {
        return match("none", "terminal_state", false, []);
    }
    if (input.sourceSpecificationState === "stale") {
        return match("recertify_plan", "stale_specification_revision", true, []);
    }
    if (activeBlockers.length > 0 || input.taskStatus === "blocked") {
        return match("resolve_blocker", "active_blocker", true, activeBlockers);
    }
    if (input.authorizationState === "stale"
        && input.currentAttemptState === "open-baseline-only") {
        return match("supersede_attempt", "contract_revision_requires_attempt_supersession", false, []);
    }
    if (input.authorizationState === "stale"
        && input.currentAttemptState === "open-evidence-bearing") {
        return match("recover_contract_revision", "contract_revision_requires_evidence_recovery", false, []);
    }
    if (input.authorizationState === "stale") {
        return match("refine_task", "stale_readiness_authorization", true, []);
    }
    if (input.readinessState === "missing"
        || input.readinessState === "incomplete"
        || input.readinessState === "unknown"
        || input.readinessState === undefined) {
        return match("refine_task", "readiness_incomplete", true, []);
    }
    if (input.reviewDisposition === "changes_requested") {
        return match("revise", "review_changes_requested", false, []);
    }
    if (input.implementationStatus === "not_started"
        || input.implementationStatus === "pending"
        || input.implementationStatus === "in_progress"
        || input.implementationStatus === null
        || input.implementationStatus === undefined) {
        return match("implement", "implementation_incomplete", false, []);
    }
    if (input.validationState === "missing"
        || input.validationState === "stale"
        || input.validationState === "blocked"
        || input.validationState === "failed"
        || input.validationState === "unknown"
        || input.validationState === undefined) {
        return match("address_validation", "validation_incomplete", true, validationFindings);
    }
    if (input.implementationStatus === "completed"
        && (input.reviewDisposition === "pending" || input.reviewDisposition === null
            || input.reviewDisposition === undefined || input.reviewDisposition === "blocked")) {
        return match("review", "review_pending", false, []);
    }
    if (input.implementationStatus === "completed"
        && (input.reviewDisposition === "accepted"
            || input.reviewDisposition === "accepted_with_follow_up"
            || input.reviewDisposition === "waived")
        && input.closeoutRecorded !== true) {
        return match("close", "accepted_not_closed", false, []);
    }
    if (input.reconciliationState === "ready") {
        return match("reconcile", "reconciliation_ready", false, []);
    }
    return match("none", "insufficient_evidence", true, []);
}
function match(nextAction, reasonCode, blocking, findings) {
    return { nextAction, reasonCode, blocking, findings };
}
function normalizeFindings(findings) {
    const byIdentity = new Map();
    for (const finding of findings) {
        const normalized = {
            code: finding.code.trim(),
            message: finding.message.trim(),
            path: normalizeOptional(finding.path)
        };
        if (normalized.code === "" || normalized.message === "")
            continue;
        const identity = [
            normalized.code,
            normalized.path ?? "",
            normalized.message
        ].join("\u0000");
        byIdentity.set(identity, normalized);
    }
    return [...byIdentity.values()].sort((left, right) => left.code.localeCompare(right.code)
        || (left.path ?? "").localeCompare(right.path ?? "")
        || left.message.localeCompare(right.message));
}
function normalizeAlternatives(candidates, blockingPrimary) {
    const byIdentity = new Map();
    for (const candidate of candidates) {
        const evidenceRefs = [...new Set(candidate.evidenceRefs.map((value) => value.trim()).filter(Boolean))]
            .sort((left, right) => left.localeCompare(right));
        if (evidenceRefs.length === 0)
            continue;
        if (blockingPrimary && candidate.compatibleWithBlockingPrimary !== true)
            continue;
        const normalized = {
            nextAction: candidate.nextAction,
            reasonCode: candidate.reasonCode,
            evidenceRefs
        };
        const identity = [
            normalized.nextAction,
            normalized.reasonCode,
            normalized.evidenceRefs.join("\u0000")
        ].join("\u0001");
        byIdentity.set(identity, normalized);
    }
    return [...byIdentity.values()].sort((left, right) => ACTION_ORDER.indexOf(left.nextAction) - ACTION_ORDER.indexOf(right.nextAction)
        || left.reasonCode.localeCompare(right.reasonCode)
        || left.evidenceRefs.join("\u0000").localeCompare(right.evidenceRefs.join("\u0000")));
}
function normalizeOptional(value) {
    if (value === null || value === undefined)
        return null;
    const normalized = value.trim();
    return normalized === "" ? null : normalized;
}
