/**
 * Steerable Autonomous Mode - Interactive Control Panel
 *
 * Provides Shift+Tab interface for steering and asking questions
 * during autonomous execution, similar to Copilot Auto.
 * Also integrates Ctrl+Y for YOLO mode (bypass git prompts).
 */

import { createInterface } from "node:readline";

import { NOTICE_KIND } from "./notification-store.js";

// ─── Constants ──────────────────────────────────────────────────────────────
const PANEL_WIDTH = 60;
const PANEL_HEIGHT = 12;

const CONTROL_CATEGORIES = [
	{
		name: "🎯 Steering",
		items: [
			{ key: "1", label: "Focus on research", action: "focus_research" },
			{ key: "2", label: "Focus on planning", action: "focus_plan" },
			{ key: "3", label: "Focus on implementation", action: "focus_build" },
			{ key: "4", label: "Speed up execution", action: "speed_up" },
			{ key: "5", label: "Slow down execution", action: "slow_down" },
		],
	},
	{
		name: "❓ Ask Questions",
		items: [
			{ key: "q", label: "What are you working on?", action: "ask_status" },
			{ key: "w", label: "Why this approach?", action: "ask_reasoning" },
			{ key: "e", label: "What's next?", action: "ask_next" },
			{ key: "r", label: "Are you stuck?", action: "ask_stuck" },
			{ key: "t", label: "Explain your plan", action: "ask_plan" },
		],
	},
	{
		name: "🔄 Retry Status",
		items: [
			{
				key: "a",
				label: "What attempts have been tried?",
				action: "ask_attempts",
			},
			{
				key: "z",
				label: "Why give up? What blockers?",
				action: "ask_blockers",
			},
			{ key: "r", label: "Reassess and try new approach", action: "reassess" },
		],
	},
	{
		name: "⚡ Quick Controls",
		items: [
			{ key: "p", label: "Pause autonomous", action: "pause" },
			{ key: "s", label: "Stop execution", action: "stop" },
			{ key: "y", label: "YOLO mode (Ctrl+Y)", action: "yolo" },
			{ key: "h", label: "Help/commands", action: "help" },
			{ key: "esc", label: "Close panel", action: "close" },
		],
	},
];

// ─── UI Rendering ─────────────────────────────────────────────────────────────

function renderBox(lines, title = "") {
	const width = PANEL_WIDTH;
	const horizontalBorder = "─".repeat(width - 2);

	let result = `┌─${title} ${horizontalBorder.slice(title.length + 1)}─┐\n`;

	for (const line of lines) {
		const padded = line.padEnd(width - 2, " ");
		result += `│ ${padded} │\n`;
	}

	result += `└─${horizontalBorder}─┘\n`;
	return result;
}

function renderCategory(category) {
	const lines = [`\x1b[1m${category.name}\x1b[0m`];

	for (const item of category.items) {
		const keyDisplay = item.key === "esc" ? "Esc" : item.key.toUpperCase();
		lines.push(`  ${keyDisplay}. ${item.label}`);
	}

	return lines;
}

function renderPanel(currentStatus = "") {
	const categories = CONTROL_CATEGORIES;

	const panelContent = [];

	// Add status line if provided
	if (currentStatus) {
		panelContent.push(`🤖 ${currentStatus}`);
		panelContent.push(""); // empty line
	}

	// Render all categories
	for (const category of categories) {
		panelContent.push(...renderCategory(category));
		if (category !== categories[categories.length - 1]) {
			panelContent.push(""); // spacing between categories
		}
	}

	// Add footer
	panelContent.push("");
	panelContent.push(
		"\x1b[90mShift+Tab or / to open/close • Ctrl+Y for YOLO\x1b[0m",
	);

	return renderBox(panelContent, "🎛️ Steerable Autonomous Mode");
}

// ─── Notification helpers ─────────────────────────────────────────────────────

/**
 * Build durable-notification metadata for steerable panel shortcuts so the store can classify and dedupe.
 *
 * Purpose: single source of truth for `noticeKind` / `dedupe_key` on user-initiated steering feedback (no duplicated option blobs per shortcut).
 *
 * Consumer: `notifySteeringPanel` and tests asserting stable metadata contracts.
 *
 * @param {string} actionId Stable handler id (matches CONTROL_CATEGORIES `action` values and YOLO variants).
 * @returns {{ noticeKind: string; dedupe_key: string; source: string }}
 */
export function buildSteeringPanelNotifyMeta(actionId) {
	return {
		noticeKind: NOTICE_KIND.USER_VISIBLE,
		dedupe_key: `steer-panel:${actionId}`,
		source: "steerable-autonomous-panel",
	};
}

/**
 * Emit one panel shortcut acknowledgement through `ctx.ui.notify` with consistent metadata.
 *
 * Purpose: keep steering toasts classifiable and merge-friendly when the user spams a hotkey.
 *
 * Consumer: ACTION_HANDLERS below.
 *
 * @param {{ ui: { notify: (msg: string, level?: string, meta?: object) => void } }} ctx
 * @param {string} actionId
 * @param {string} message
 * @param {"info"|"success"|"warning"|"error"} [level]
 */
function notifySteeringPanel(ctx, actionId, message, level = "info") {
	ctx.ui.notify(message, level, buildSteeringPanelNotifyMeta(actionId));
}

/** Stub copy for shortcuts — replace with live AI/runtime wiring when those actions are implemented. */
const STEERING_ACK_TEXT = {
	focus_research: "🎯 Focusing on research phase",
	focus_plan: "🎯 Focusing on planning phase",
	focus_build: "🎯 Focusing on implementation phase",
	speed_up: "⚡ Execution speed increased",
	slow_down: "🐌 Execution speed decreased",
	ask_status: "🤖 I'm currently working on [current task]",
	ask_reasoning: "🤖 I chose this approach because...",
	ask_next: "🤖 Next I'll [next step]",
	ask_stuck: "🤖 I'm not stuck, but here's my status...",
	ask_plan: "🤖 My plan is: [detailed plan]",
	pause: "⏸️ Autonomous mode paused",
	ask_attempts: "🤖 I've tried multiple approaches: [list of attempts]",
	ask_blockers: "🤖 Main blockers: [list of current blockers]",
	reassess: "🔄 Reassessing - trying new approaches",
};

/**
 * @param {keyof typeof STEERING_ACK_TEXT} actionId
 */
function simpleSteeringHandler(actionId) {
	return async (ctx) => {
		notifySteeringPanel(ctx, actionId, STEERING_ACK_TEXT[actionId], "info");
	};
}

// ─── Action Handlers ────────────────────────────────────────────────────────────

const ACTION_HANDLERS = {
	focus_research: simpleSteeringHandler("focus_research"),
	focus_plan: simpleSteeringHandler("focus_plan"),
	focus_build: simpleSteeringHandler("focus_build"),
	speed_up: simpleSteeringHandler("speed_up"),
	slow_down: simpleSteeringHandler("slow_down"),
	ask_status: simpleSteeringHandler("ask_status"),
	ask_reasoning: simpleSteeringHandler("ask_reasoning"),
	ask_next: simpleSteeringHandler("ask_next"),
	ask_stuck: simpleSteeringHandler("ask_stuck"),
	ask_plan: simpleSteeringHandler("ask_plan"),
	pause: simpleSteeringHandler("pause"),
	ask_attempts: simpleSteeringHandler("ask_attempts"),
	ask_blockers: simpleSteeringHandler("ask_blockers"),
	reassess: simpleSteeringHandler("reassess"),

	yolo: async (ctx) => {
		if (ctx.settingsManager?.toggleYOLO) {
			const enabled = ctx.settingsManager.toggleYOLO();
			const msg = `🚀 YOLO mode ${enabled ? "ON" : "OFF"} - safe-git prompts ${enabled ? "disabled" : "enabled"}`;
			notifySteeringPanel(
				ctx,
				enabled ? "yolo-on" : "yolo-off",
				msg,
				enabled ? "success" : "info",
			);
		} else {
			notifySteeringPanel(
				ctx,
				"yolo-stub",
				"🚀 YOLO mode - safe-git prompts disabled for this session",
				"success",
			);
		}
	},

	help: async (ctx) => {
		const helpText = renderPanel("Available controls shown above");
		notifySteeringPanel(
			ctx,
			"help",
			`Steerable Autonomous Mode Help\n\n${helpText}`,
			"info",
		);
	},

	close: async (_ctx) => {
		// Just hide the panel
	},
};

// ─── Panel Controller ──────────────────────────────────────────────────────────

export class SteerableAutonomousPanel {
	constructor(ctx) {
		this.ctx = ctx;
		this.isVisible = false;
		this.rl = null;
	}

	async show() {
		if (this.isVisible) return;

		this.isVisible = true;
		this.rl = createInterface({
			input: process.stdin,
			output: process.stdout,
			terminal: true,
		});

		// Hide cursor while panel is open
		process.stdout.write("\x1b[?25l");

		// Render panel
		this.render();

		// Set up key listener
		this.rl.input.on("keypress", (_str, key) => {
			this.handleKeyPress(key);
		});
	}

	hide() {
		if (!this.isVisible) return;

		this.isVisible = false;

		// Restore cursor
		process.stdout.write("\x1b[?25h");

		// Clear the panel area
		process.stdout.write("\x1b[" + PANEL_HEIGHT + "F"); // Move cursor up
		process.stdout.write("\x1b[0J"); // Clear from cursor down

		if (this.rl) {
			this.rl.close();
			this.rl = null;
		}
	}

	async render() {
		if (!this.isVisible) return;

		// Get current autonomous status (would come from actual system)
		const currentStatus = "Working on current milestone...";

		const panel = renderPanel(currentStatus);

		// Move cursor to panel area
		process.stdout.write("\x1b[s"); // Save current position
		process.stdout.write("\x1b[H"); // Move to top-left
		process.stdout.write(panel);
		process.stdout.write("\x1b[u"); // Restore saved position
	}

	async handleKeyPress(key) {
		if (!this.isVisible) return;

		// Handle escape sequences
		if (key.name === "escape") {
			this.hide();
			return;
		}

		// Find matching action
		let actionKey = key.name || key.sequence?.toLowerCase() || "";

		// Handle single character keys
		if (actionKey.length === 1) {
			actionKey = actionKey.toLowerCase();
		}

		// Find action
		let action = null;
		for (const category of CONTROL_CATEGORIES) {
			const item = category.items.find((item) => item.key === actionKey);
			if (item) {
				action = item;
				break;
			}
		}

		if (action) {
			await ACTION_HANDLERS[action.action](this.ctx);

			// If it's not a close action, re-render panel
			if (action.action !== "close") {
				this.render();
			}
		}
	}
}

// ─── Integration Hook ──────────────────────────────────────────────────────────

let activePanel = null;

export async function showSteerablePanel(ctx) {
	if (activePanel) {
		activePanel.hide();
	}

	activePanel = new SteerableAutonomousPanel(ctx);
	await activePanel.show();
}

export async function hideSteerablePanel() {
	if (activePanel) {
		activePanel.hide();
		activePanel = null;
	}
}

// ─── Keyboard Integration (would integrate with TUI's key handler) ──────────

export function handleSteerableModeKey(key) {
	// Shift+Tab opens/closes the panel
	if (key.shift && key.name === "tab") {
		return true; // Signal that we handled this key
	}
	return false;
}

export default {
	show: showSteerablePanel,
	hide: hideSteerablePanel,
	handleKey: handleSteerableModeKey,
};
