// SF Command — `/escalate` (SF ADR-011 P2)
//
// Subcommands:
//   list [--all]              — show active escalations; --all also includes resolved
//   show <slice>/<task>       — print the escalation question + options for one task
//   resolve <slice>/<task> <option> [-- <rationale>]
//                             — apply user choice, clear flag, allow loop to continue
//
// All operations run against the active project's DB (process.cwd()-rooted).
import { ensureDbOpen } from "./bootstrap/dynamic-tools.js";
import { readEscalationArtifact, resolveEscalation } from "./escalation.js";
import {
	getActiveMilestoneFromDb,
	getSliceTasks,
	isDbAvailable,
	listEscalationArtifacts,
} from "./sf-db.js";

function usage() {
	return [
		"Usage: /escalate <subcommand>",
		"",
		"Subcommands:",
		"  list [--all]                           List active escalations (--all also shows resolved)",
		"  show <sliceId>/<taskId>                Show escalation details",
		"  resolve <sliceId>/<taskId> <option> [-- <rationale>]",
		"                                         Apply user choice (option id or 'accept')",
	].join("\n");
}
function parseSliceTask(spec) {
	const m = spec.match(/^(S\d+[A-Za-z0-9-]*)\/(T\d+[A-Za-z0-9-]*)$/);
	if (!m) return null;
	return { sliceId: m[1], taskId: m[2] };
}
export async function handleEscalate(args, ctx) {
	await ensureDbOpen(process.cwd());
	if (!isDbAvailable()) {
		ctx.ui.notify("SF database is not available. Run /doctor.", "error");
		return;
	}
	const trimmed = args.trim();
	if (!trimmed) {
		ctx.ui.notify(usage(), "info");
		return;
	}
	const [sub, ...rest] = trimmed.split(/\s+/);
	if (sub === "list") {
		const ms = getActiveMilestoneFromDb();
		if (!ms) {
			ctx.ui.notify("No active milestone — nothing to list.", "info");
			return;
		}
		// Pass --all to also list resolved escalations (audit trail).
		const includeResolved = rest.includes("--all");
		const tasks = listEscalationArtifacts(ms.id, includeResolved);
		const header = includeResolved
			? `Escalations for milestone ${ms.id} (active + resolved):`
			: `Active escalations for milestone ${ms.id}:`;
		const lines = [header];
		let count = 0;
		for (const task of tasks) {
			if (!task.escalation_artifact_path) continue;
			const art = readEscalationArtifact(task.escalation_artifact_path);
			if (!art) continue;
			count++;
			const isAutoResolved =
				art.respondedAt && art.userRationale?.startsWith("autonomous mode:");
			const status =
				task.escalation_pending === 1
					? "PENDING"
					: task.escalation_awaiting_review === 1
						? "awaiting-review"
						: art.respondedAt
							? isAutoResolved
								? `auto-accepted (${art.userChoice})`
								: `resolved (${art.userChoice})`
							: "(unknown)";
			lines.push(`  ${task.slice_id}/${task.id} [${status}]: ${art.question}`);
			if (status === "PENDING") {
				lines.push(`     options: ${art.options.map((o) => o.id).join(", ")}`);
				lines.push(`     recommend: ${art.recommendation}`);
			}
		}
		if (count === 0) {
			ctx.ui.notify(
				includeResolved
					? "No escalations recorded."
					: "No active escalations. Use /escalate list --all to include resolved.",
				"info",
			);
			return;
		}
		ctx.ui.notify(lines.join("\n"), "info");
		return;
	}
	if (sub === "show") {
		const spec = rest[0];
		const parsed = spec ? parseSliceTask(spec) : null;
		if (!parsed) {
			ctx.ui.notify(
				"Usage: /escalate show <sliceId>/<taskId>  (e.g. S01/T01)",
				"warning",
			);
			return;
		}
		const ms = getActiveMilestoneFromDb();
		if (!ms) {
			ctx.ui.notify("No active milestone.", "warning");
			return;
		}
		const tasks = getSliceTasks(ms.id, parsed.sliceId);
		const task = tasks.find((t) => t.id === parsed.taskId);
		if (!task || !task.escalation_artifact_path) {
			ctx.ui.notify(
				`No escalation found for ${parsed.sliceId}/${parsed.taskId}.`,
				"warning",
			);
			return;
		}
		const art = readEscalationArtifact(task.escalation_artifact_path);
		if (!art) {
			ctx.ui.notify(
				`Escalation artifact at ${task.escalation_artifact_path} is missing or malformed.`,
				"error",
			);
			return;
		}
		const out = [
			`Escalation: ${ms.id}/${parsed.sliceId}/${parsed.taskId}`,
			`Question: ${art.question}`,
			"",
			"Options:",
		];
		for (const o of art.options) {
			const isRec = o.id === art.recommendation ? " (recommended)" : "";
			out.push(`  ${o.id}: ${o.label}${isRec}`);
			if (o.tradeoffs) out.push(`     tradeoffs: ${o.tradeoffs}`);
		}
		out.push(`\nRationale for recommendation: ${art.recommendationRationale}`);
		if (art.respondedAt) {
			const isAutoResolved = art.userRationale?.startsWith("autonomous mode:");
			const verb = isAutoResolved ? "Auto-accepted" : "Resolved";
			out.push(
				`\n${verb} ${art.respondedAt} → choice="${art.userChoice}"${art.userRationale ? ` (rationale: ${art.userRationale})` : ""}`,
			);
		} else {
			out.push(
				`\nUnresolved. Run /escalate resolve ${parsed.sliceId}/${parsed.taskId} <option-id|accept>`,
			);
		}
		ctx.ui.notify(out.join("\n"), "info");
		return;
	}
	if (sub === "resolve") {
		const spec = rest[0];
		const parsed = spec ? parseSliceTask(spec) : null;
		if (!parsed) {
			ctx.ui.notify(
				"Usage: /escalate resolve <sliceId>/<taskId> <option> [-- <rationale>]",
				"warning",
			);
			return;
		}
		const choice = rest[1];
		if (!choice) {
			ctx.ui.notify(
				"Missing choice. Pass 'accept' or one of the artifact's option ids.",
				"warning",
			);
			return;
		}
		// Optional `-- <rationale>` separator
		const dashIdx = rest.indexOf("--");
		const rationale = dashIdx >= 0 ? rest.slice(dashIdx + 1).join(" ") : "";
		const ms = getActiveMilestoneFromDb();
		if (!ms) {
			ctx.ui.notify("No active milestone.", "warning");
			return;
		}
		const result = resolveEscalation(
			process.cwd(),
			ms.id,
			parsed.sliceId,
			parsed.taskId,
			choice,
			rationale,
		);
		const level =
			result.status === "resolved"
				? "info"
				: result.status === "invalid-choice" ||
						result.status === "already-resolved"
					? "warning"
					: "error";
		ctx.ui.notify(result.message, level);
		return;
	}
	ctx.ui.notify(`Unknown subcommand "${sub}".\n${usage()}`, "warning");
}
