// ABOUTME: Double-tap ESC cancels all running operations (agent stream, subagents, chains, pipelines).
// ABOUTME: Listens for raw terminal ESC input and detects two presses within 400ms.

import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
import { matchesKey } from "@mariozechner/pi-tui";
import { applyExtensionDefaults } from "./lib/themeMap.ts";

/** Time window (ms) for two ESC presses to be considered a double-tap. */
const DOUBLE_TAP_WINDOW = 400;

export default function (pi: ExtensionAPI) {
	let lastEscTime = 0;
	let unsub: (() => void) | null = null;
	let isAgentRunning = false;

	function cancelAll(ctx: any) {
		const g = globalThis as any;
		let cancelled = false;

		// 1. Abort the main agent stream
		if (!ctx.isIdle()) {
			ctx.abort();
			cancelled = true;
		}

		// 2. Kill all running subagents (exposed by subagent-widget.ts)
		if (typeof g.__piKillAllSubagents === "function") {
			const killed = g.__piKillAllSubagents();
			if (killed > 0) cancelled = true;
		}

		// 3. Kill running chain process (exposed by agent-chain.ts)
		if (typeof g.__piKillChainProc === "function") {
			if (g.__piKillChainProc()) cancelled = true;
		}

		// 4. Kill running pipeline processes (exposed by pipeline-team.ts)
		if (typeof g.__piKillPipelineProc === "function") {
			if (g.__piKillPipelineProc()) cancelled = true;
		}

		// 5. Kill running team agent processes (exposed by agent-team.ts)
		if (typeof g.__piKillTeamProcs === "function") {
			const killed = g.__piKillTeamProcs();
			if (killed > 0) cancelled = true;
		}

		if (cancelled) {
			ctx.ui.notify("All operations cancelled (ESC ESC)", "warning");
		}
	}

	function setupInputListener(ctx: any) {
		if (unsub) return; // Already listening

		unsub = ctx.ui.onTerminalInput((data: string) => {
			// Only detect bare ESC key
			if (!matchesKey(data, "escape")) return undefined;

			const now = Date.now();
			if (now - lastEscTime < DOUBLE_TAP_WINDOW) {
				// Double-tap detected
				lastEscTime = 0;
				// Only cancel if something is actually running
				if (!ctx.isIdle() || hasRunningOperations()) {
					cancelAll(ctx);
					return { consume: true };
				}
			} else {
				lastEscTime = now;
			}

			// Don't consume — let the normal ESC handler work
			return undefined;
		});
	}

	/** Check if there are running subagents, chains, or pipelines. */
	function hasRunningOperations(): boolean {
		const g = globalThis as any;

		// Check subagents
		if (typeof g.__piHasRunningSubagents === "function" && g.__piHasRunningSubagents()) {
			return true;
		}

		// Check chain
		if (g.__piActiveChain && typeof g.__piHasRunningChain === "function" && g.__piHasRunningChain()) {
			return true;
		}

		// Check pipeline
		if (g.__piActivePipeline && typeof g.__piHasRunningPipeline === "function" && g.__piHasRunningPipeline()) {
			return true;
		}

		// Check team
		if (typeof g.__piHasRunningTeam === "function" && g.__piHasRunningTeam()) {
			return true;
		}

		return false;
	}

	// ── Track agent state for status hint ─────────────────

	pi.on("agent_start", async (_event, ctx) => {
		isAgentRunning = true;
		if (ctx.hasUI) {
			ctx.ui.setStatus("esc-hint", "\x1b[2m ESC ESC to cancel\x1b[0m");
		}
	});

	pi.on("agent_end", async (_event, ctx) => {
		isAgentRunning = false;
		if (ctx.hasUI) {
			ctx.ui.setStatus("esc-hint", undefined);
		}
	});

	// ── Session lifecycle ─────────────────────────────────

	pi.on("session_start", async (_event, ctx) => {
		applyExtensionDefaults(import.meta.url, ctx);
		lastEscTime = 0;
		isAgentRunning = false;
		if (ctx.hasUI) {
			setupInputListener(ctx);
		}
	});

	pi.on("session_switch", async (_event, ctx) => {
		lastEscTime = 0;
		isAgentRunning = false;
		if (ctx.hasUI) {
			ctx.ui.setStatus("esc-hint", undefined);
		}
	});

	pi.on("session_shutdown", async () => {
		if (unsub) {
			unsub();
			unsub = null;
		}
	});
}
