import { randomUUID } from "node:crypto";
import { emitJournalEvent } from "./journal.js";
import { appendTraceEvent } from "./uok/trace-writer.js";

const ROUTE_TRACE_PREFIX = "[sf-route:";
const ROUTE_TRACE_SUFFIX = "]";
const MAX_PENDING_ROUTE_TRACES = 50;
const pendingRouteTraces = [];

const ROUTES = [
	{
		command: "help",
		patterns: [
			/^(help|show help|open help|what can i do|show commands?|list commands?)$/i,
		],
	},
	{
		command: "queue",
		patterns: [
			/\b(show|open|view|list|see|what'?s in|what is in)\b.*\bqueue\b/i,
			/\bqueue\b.*\b(show|open|view|list)\b/i,
		],
	},
	{
		command: "status",
		patterns: [
			/\b(show|open|view|check|what'?s|what is|where are we)\b.*\b(status|progress|dashboard)\b/i,
			/\bhow far\b/i,
		],
	},
	{
		command: "history",
		patterns: [/\b(show|open|view|list)\b.*\b(history|what happened)\b/i],
	},
	{
		command: "logs",
		patterns: [/\b(show|open|view|tail|read)\b.*\b(logs?|debug logs?)\b/i],
	},
	{
		command: "forensics",
		patterns: [/\b(run|open|show|start)\b.*\bforensics?\b/i],
	},
	{
		command: "visualize",
		patterns: [/\b(open|show|view)\b.*\b(visuali[sz]e|visuali[sz]er|graph)\b/i],
	},
	{
		command: "doctor",
		patterns: [/\b(run|open|check)\b.*\b(doctor|health|diagnostics?)\b/i],
	},
	{
		command: "repair",
		patterns: [/\b(run|start|switch to)\b.*\brepair\b/i],
	},
	{
		command: "autonomous",
		patterns: [
			/\b(start|run|go|continue|resume)\b.*\b(autonomous|autonomy|auto mode)\b/i,
			/\bkeep going\b/i,
		],
	},
	{
		command: "next",
		patterns: [/\b(run|do|take|start)\b.*\b(next step|next unit|one step)\b/i],
	},
	{
		command: "discuss",
		patterns: [
			/\b(start|open|enter)\b.*\b(discuss|discussion|planning|plan mode)\b/i,
			/\b(let'?s|lets)\b.*\b(discuss|plan)\b/i,
		],
	},
	{
		command: "quick",
		patterns: [/\b(run|do|use)\b.*\bquick\b/i, /^quickly?\b/i],
		preserveArgs: true,
	},
	{
		command: "capture",
		patterns: [/\b(capture|remember|note)\b.*\b(this|that|idea|thought)\b/i],
		preserveArgs: true,
	},
	{
		command: "triage",
		patterns: [/\b(run|start|apply|do)\b.*\btriage\b/i],
	},
	{
		command: "pause",
		patterns: [
			/^(pause|take a break)$/i,
			/\bpause\b.*\b(autonomous|sf|run|workflow)\b/i,
		],
	},
	{
		command: "stop",
		patterns: [/\b(stop|halt)\b.*\b(autonomous|run|sf)\b/i],
	},
	{
		command: "undo",
		patterns: [/\b(undo|revert|roll back)\b.*\b(last|previous|change|step)\b/i],
	},
	{
		command: "skip",
		patterns: [/\bskip\b.*\b(task|unit|this)\b/i],
		preserveArgs: true,
	},
];

function normalizeArgs(text) {
	return text.replace(/\s+/g, " ").trim();
}

export function classifyChatCommand(text) {
	const input = normalizeArgs(text);
	if (!input || input.startsWith("/") || input.startsWith("!")) return null;
	if (input.length > 240) return null;

	for (const route of ROUTES) {
		if (!route.patterns.some((pattern) => pattern.test(input))) continue;
		const args = route.preserveArgs ? input : "";
		return {
			input,
			command: route.command,
			args,
			routedText: args ? `/${route.command} ${args}` : `/${route.command}`,
			confidence: "high",
			outcome: "routed",
			nextAction: `execute /${route.command}`,
		};
	}
	return null;
}

export function routeChatCommand(text) {
	return classifyChatCommand(text)?.routedText ?? null;
}

function emitChatIntentEvidence(basePath, decision) {
	if (!basePath || !decision) return;
	const flowId = decision.traceId ?? `chat-intent:${randomUUID()}`;
	const event = {
		input: decision.input,
		routedText: decision.routedText,
		command: decision.command,
		args: decision.args,
		confidence: decision.confidence,
		outcome: decision.outcome,
		nextAction: decision.nextAction,
	};
	emitJournalEvent(basePath, {
		ts: new Date().toISOString(),
		flowId,
		seq: 1,
		eventType: "chat-intent-routed",
		rule: "chat-command-router",
		data: event,
	});
	appendTraceEvent(basePath, flowId, {
		type: "chat_intent",
		surface: "interactive",
		runControl: "assisted",
		permissionProfile: "normal",
		...event,
	});
}

export function extractRouteTracePrefix(text) {
	if (!text?.startsWith(ROUTE_TRACE_PREFIX)) {
		return { text, routeTraceId: null };
	}
	const end = text.indexOf(ROUTE_TRACE_SUFFIX);
	if (end === -1) return { text, routeTraceId: null };
	const routeTraceId = text.slice(ROUTE_TRACE_PREFIX.length, end);
	const stripped = text.slice(end + ROUTE_TRACE_SUFFIX.length).trimStart();
	return { text: stripped, routeTraceId };
}

export function consumeRouteTraceForCommand(command) {
	const index = pendingRouteTraces.findIndex(
		(entry) => entry.command === command,
	);
	if (index === -1) return null;
	const [entry] = pendingRouteTraces.splice(index, 1);
	return entry;
}

export function registerChatCommandRouter(pi) {
	pi.on("input", (event, ctx) => {
		if (event.source === "extension") return { action: "continue" };
		if (event.images?.length > 0) return { action: "continue" };
		const decision = classifyChatCommand(event.text);
		if (!decision) return { action: "continue" };
		decision.traceId = `chat-intent:${randomUUID()}`;
		emitChatIntentEvidence(ctx?.cwd, decision);
		pendingRouteTraces.push({
			command: decision.command,
			traceId: decision.traceId,
			input: decision.input,
			routedText: decision.routedText,
		});
		if (pendingRouteTraces.length > MAX_PENDING_ROUTE_TRACES) {
			pendingRouteTraces.shift();
		}
		return {
			action: "transform",
			text: `${ROUTE_TRACE_PREFIX}${decision.traceId}${ROUTE_TRACE_SUFFIX} ${decision.routedText}`,
			images: event.images,
		};
	});
}
