/**
 * SF Triage UI — Confirmation flow for programmatic triage results
 *
 * Used by autonomous mode dispatch (S02) when triage fires between tasks.
 * For manual `/triage`, the LLM session handles confirmation directly.
 *
 * This module provides `showTriageConfirmation` which presents each
 * triage result to the user via `showNextAction` and returns the
 * confirmed classifications.
 */
import { showNextAction } from "../shared/tui.js";
import { markCaptureResolved } from "./captures.js";
import { ensureDeferMilestoneDir } from "./triage-resolution.js";

// ─── Classification Labels ────────────────────────────────────────────────────
const CLASSIFICATION_LABELS = {
	"quick-task": {
		label: "Quick task",
		description:
			"Execute as a one-off at the next seam — no plan modification.",
	},
	inject: {
		label: "Inject into plan",
		description: "Add a new task to the current slice plan.",
	},
	defer: {
		label: "Defer",
		description: "Move to a future slice or milestone — not urgent now.",
	},
	replan: {
		label: "Replan slice",
		description: "Remaining tasks need rewriting — triggers slice replan.",
	},
	note: {
		label: "Note",
		description: "Informational only — no action needed.",
	},
	stop: {
		label: "Stop",
		description:
			"Halt autonomous mode immediately — user directive to cease execution.",
	},
	backtrack: {
		label: "Backtrack",
		description: "Abandon current milestone and return to a previous one.",
	},
};
const ALL_CLASSIFICATIONS = [
	"quick-task",
	"inject",
	"defer",
	"replan",
	"note",
	"stop",
	"backtrack",
];
// ─── Public API ───────────────────────────────────────────────────────────────
/**
 * Present triage results to the user for confirmation.
 *
 * For each capture:
 * - note/defer: auto-confirm (no user interaction needed)
 * - quick-task/inject/replan: show confirmation UI with proposed + alternatives
 *
 * Returns confirmed results with final classifications.
 * Updates CAPTURES.md with resolved status.
 *
 * @param fileOverlaps - Map of captureId → list of planned task IDs whose files overlap
 */
export async function showTriageConfirmation(
	ctx,
	triageResults,
	captures,
	basePath,
	fileOverlaps,
) {
	const confirmed = [];
	const captureMap = new Map(captures.map((c) => [c.id, c]));
	for (const result of triageResults) {
		const capture = captureMap.get(result.captureId);
		if (!capture) continue;
		// Auto-confirm note, defer, stop, and backtrack — low-impact or urgent directives
		if (
			result.classification === "note" ||
			result.classification === "defer" ||
			result.classification === "stop" ||
			result.classification === "backtrack"
		) {
			const resolution =
				result.classification === "note"
					? "acknowledged as note"
					: `deferred${result.targetSlice ? ` to ${result.targetSlice}` : ""}`;
			markCaptureResolved(
				basePath,
				result.captureId,
				result.classification,
				resolution,
				result.rationale,
			);
			// Create the milestone directory when deferring to a milestone that
			// doesn't exist yet, so deriveState() discovers it.
			if (result.classification === "defer" && result.targetSlice) {
				ensureDeferMilestoneDir(basePath, result.targetSlice, [capture]);
			}
			confirmed.push({
				captureId: result.captureId,
				classification: result.classification,
				rationale: result.rationale,
				affectedFiles: result.affectedFiles,
				targetSlice: result.targetSlice,
				userOverride: false,
			});
			continue;
		}
		// Build summary lines for the confirmation UI
		const summary = [
			`"${capture.text}"`,
			"",
			`Proposed: **${CLASSIFICATION_LABELS[result.classification].label}** — ${result.rationale}`,
		];
		// Add file overlap warning if present
		const overlaps = fileOverlaps?.get(result.captureId);
		if (overlaps && overlaps.length > 0) {
			summary.push("");
			summary.push(
				`⚠ Touches files planned for ${overlaps.join(", ")} — consider inject or defer`,
			);
		}
		if (result.affectedFiles && result.affectedFiles.length > 0) {
			summary.push("");
			summary.push(`Files: ${result.affectedFiles.join(", ")}`);
		}
		// Build action options — proposed first (recommended), then alternatives
		const proposed = result.classification;
		const actions = ALL_CLASSIFICATIONS.map((cls) => ({
			id: cls,
			label: CLASSIFICATION_LABELS[cls].label,
			description: CLASSIFICATION_LABELS[cls].description,
			recommended: cls === proposed,
		}));
		const choice = await showNextAction(ctx, {
			title: `Triage: ${result.captureId}`,
			summary,
			actions,
			notYetMessage: "Capture will remain pending for later triage.",
		});
		if (choice === "not_yet") {
			// User skipped — leave capture pending
			continue;
		}
		const finalClassification = choice;
		const userOverride = finalClassification !== proposed;
		const resolution = userOverride
			? `user chose ${finalClassification} (was ${proposed})`
			: `confirmed as ${finalClassification}`;
		markCaptureResolved(
			basePath,
			result.captureId,
			finalClassification,
			resolution,
			userOverride ? `User override: ${result.rationale}` : result.rationale,
		);
		// Create the milestone directory when user confirms/overrides to defer
		if (finalClassification === "defer" && result.targetSlice) {
			ensureDeferMilestoneDir(basePath, result.targetSlice, [capture]);
		}
		confirmed.push({
			captureId: result.captureId,
			classification: finalClassification,
			rationale: result.rationale,
			affectedFiles: result.affectedFiles,
			targetSlice: result.targetSlice,
			userOverride,
		});
	}
	return confirmed;
}
