import path from "node:path";
import { pathExists } from "../utils/fs.js";
import { getRuntimeSnapshot, persistRuntimeDerivedOutput } from "../runtime/client.js";
import { runtimeDecisionFromSnapshot } from "./runtime-decision.js";
export async function nextActionEngine(targetRoot, validationIssues = [], options = {}) {
    const agentDir = path.join(targetRoot, ".agent");
    if (!(await pathExists(agentDir))) {
        const action = {
            action: "Initialize this repo",
            file: null,
            command: "kiwi-control init",
            reason: "Kiwi Control has not been initialized in this folder yet.",
            priority: "critical"
        };
        return finalizeDecisionOutput(targetRoot, [action], `${action.action}: ${action.reason}`, ["repo not initialized"], ["Initialization is the first priority because no repo-local control plane exists yet."], [], options.persist !== false);
    }
    const runtimeSnapshot = await getRuntimeSnapshot(targetRoot);
    const runtimeDecision = runtimeDecisionFromSnapshot(runtimeSnapshot);
    const liveValidationAction = buildLiveValidationAction(validationIssues);
    const nextActions = liveValidationAction
        ? [liveValidationAction]
        : runtimeDecision.nextAction
            ? [{
                    ...runtimeDecision.nextAction,
                    file: null
                }]
            : [];
    const summary = nextActions[0]
        ? `${nextActions[0].action}: ${nextActions[0].reason}`
        : runtimeDecision.recovery?.reason ?? runtimeDecision.readinessDetail;
    return finalizeDecisionOutput(targetRoot, nextActions, summary, [
        `execution lifecycle: ${runtimeSnapshot.lifecycle}`,
        `current step: ${runtimeDecision.currentStepId}`,
        `decision source: ${runtimeDecision.decisionSource}`,
        `${validationIssues.length} validation issue(s)`
    ], [
        "Runtime decision state is the canonical source of truth for next-step decisions.",
        ...(liveValidationAction ? ["Live repo validation errors override calm runtime execution state."] : []),
        `The active runtime step is ${runtimeDecision.currentStepId}.`,
        ...(runtimeDecision.recovery ? [`A canonical runtime recovery is active: ${runtimeDecision.recovery.kind}.`] : [])
    ], [
        ...(runtimeDecision.recovery ? ["Ignored compatibility plan hints because runtime recovery is active."] : []),
        ...(liveValidationAction ? ["Ignored runtime next-action defaults because repo validation is currently failing."] : [])
    ], options.persist !== false);
}
async function finalizeDecisionOutput(targetRoot, nextActions, summary, inputSignals, reasoningChain, ignoredSignals, persist) {
    const topPriority = nextActions[0]?.priority ?? "low";
    const decisionLogic = {
        artifactType: "kiwi-control/decision-logic",
        version: 1,
        timestamp: new Date().toISOString(),
        summary,
        decisionPriority: topPriority,
        inputSignals,
        reasoningChain,
        ignoredSignals
    };
    if (persist) {
        await persistDecisionLogic(targetRoot, decisionLogic).catch(() => null);
    }
    return { nextActions, summary, decisionLogic };
}
async function persistDecisionLogic(targetRoot, logic) {
    const statePath = path.join(targetRoot, ".agent", "state", "decision-logic.json");
    await persistRuntimeDerivedOutput({
        targetRoot,
        outputName: "decision-logic",
        payload: logic
    });
    return statePath;
}
function buildLiveValidationAction(validationIssues) {
    const blockingIssue = validationIssues.find((issue) => issue.level === "error");
    if (!blockingIssue) {
        return null;
    }
    return {
        action: "Fix the blocking execution issue",
        file: blockingIssue.filePath ?? null,
        command: "kiwi-control doctor",
        reason: blockingIssue.message,
        priority: "critical"
    };
}
