/**
 * EasyMode — All-in-one beginner-friendly Pi extension
 *
 * Built-in features:
 *   🎯 Goal Keeper    — set a focus so the AI stays on track
 *   🛡️ Safety Guard   — catches dangerous commands before they run
 *   📊 Smart Footer   — model, context bar, cost, git branch, tool tally
 *   🤖 Agent Presets  — switch AI personality with /agent
 *   🟢 /menu          — visual command picker (no memorization needed)
 *   🛑 /stop          — abort the current AI action
 *   💡 /explain       — re-explain the last action in plain English
 *   🔖 /bookmark      — save + list important moments
 *   ↩️  /undo          — how to revert the last file change
 *   📋 /status        — full session dashboard
 *   📖 /help          — quick reference
 *   🔄 /quickstart    — re-run the welcome wizard
 *
 * Usage: pi -e extensions/easymode.ts
 *
 * Or with theme cycling:
 *   pi -e extensions/easymode.ts -e extensions/theme-cycler.ts
 */

import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
import { isToolCallEventType } from "@mariozechner/pi-coding-agent";
import type { AssistantMessage } from "@mariozechner/pi-ai";
import { truncateToWidth, visibleWidth } from "@mariozechner/pi-tui";
import { basename } from "node:path";
import { applyExtensionDefaults } from "./themeMap.ts";

// ═══════════════════════════════════════════════════════════════════════════
// Agent Presets
// ═══════════════════════════════════════════════════════════════════════════

interface AgentPreset {
	name: string;
	emoji: string;
	description: string;
	systemPrompt: string;
}

const AGENT_PRESETS: AgentPreset[] = [
	{
		name: "Default",
		emoji: "🤖",
		description: "Standard coding assistant — no restrictions",
		systemPrompt: "",
	},
	{
		name: "Explain Like I'm 5",
		emoji: "👶",
		description: "Explains everything in the simplest terms possible",
		systemPrompt: `You are a patient teacher. The user is a beginner.
- Explain EVERY concept in simple terms before using it
- Use analogies and real-world comparisons
- Show the "before" and "after" of every change
- Never assume the user knows technical jargon — define it first
- After each code change, add a brief "What just happened?" summary
- If a command could break something, warn the user FIRST`,
	},
	{
		name: "Guided Builder",
		emoji: "🏗️",
		description: "Step-by-step building with confirmations at each stage",
		systemPrompt: `You are a guided builder. Help the user build things step-by-step.
- Break every task into numbered steps and show the plan first
- Ask for confirmation before each major step
- After each change, briefly explain what you did and why
- If there are multiple approaches, list 2-3 options with pros/cons
- Always suggest the safest option as the default
- Show file paths and explain the project structure as you go`,
	},
	{
		name: "Code Reviewer",
		emoji: "🔍",
		description: "Reviews code and suggests improvements without changing anything",
		systemPrompt: `You are a code reviewer. Review, don't modify.
- DO NOT write or edit any files unless explicitly asked
- Point out bugs, security issues, and improvement opportunities
- Rate code quality on a 1-5 scale with specific reasons
- Suggest improvements as clear before/after examples
- Focus on: readability, security, performance, maintainability
- Be encouraging — highlight what's done well too`,
	},
	{
		name: "Debug Detective",
		emoji: "🕵️",
		description: "Focused on finding and fixing bugs",
		systemPrompt: `You are a debug detective. Help find and fix bugs systematically.
- Always ask to see error messages and logs first
- Explain your debugging thought process step by step
- List possible causes ranked by likelihood
- Test hypotheses one at a time
- After fixing, explain what caused the bug and how to prevent it
- Suggest adding error handling or tests to prevent recurrence`,
	},
	{
		name: "Safe Mode",
		emoji: "🔒",
		description: "Extra cautious — confirms every file modification",
		systemPrompt: `You are in Safe Mode. Maximum caution.
- ALWAYS show the exact changes you plan to make BEFORE making them
- Ask for explicit "yes" confirmation before ANY file write, edit, or bash command
- Never run destructive commands (rm, drop, truncate, etc.) without double-confirming
- Create backups before modifying existing files when possible
- After each change, verify the change was correct by reading the file back
- If something goes wrong, immediately suggest how to undo it`,
	},
];

// ═══════════════════════════════════════════════════════════════════════════
// Dangerous Command Patterns
// ═══════════════════════════════════════════════════════════════════════════

const DANGEROUS_PATTERNS: { pattern: RegExp; reason: string }[] = [
	{ pattern: /rm\s+(-[rRf]+\s+|.*\s+-[rRf]+)/, reason: "Recursive/forced delete detected" },
	{ pattern: /rm\s+-rf\s+[\/~]/, reason: "Deleting from root or home directory!" },
	{ pattern: /DROP\s+(TABLE|DATABASE|SCHEMA)/i, reason: "SQL DROP command detected" },
	{ pattern: /TRUNCATE\s+TABLE/i, reason: "SQL TRUNCATE command detected" },
	{ pattern: /DELETE\s+FROM\s+\w+\s*(;|$)/i, reason: "DELETE without WHERE clause" },
	{ pattern: />\s*\/dev\/sd[a-z]/, reason: "Writing directly to disk device" },
	{ pattern: /mkfs\./, reason: "Filesystem format command detected" },
	{ pattern: /dd\s+if=/, reason: "dd command — raw disk copy" },
	{ pattern: /chmod\s+-R\s+777/, reason: "Recursive world-writable permissions" },
	{ pattern: /:(){ :\|:& };:/, reason: "Fork bomb detected!" },
	{ pattern: /curl.*\|\s*(ba)?sh/, reason: "Piping remote script to shell" },
	{ pattern: /wget.*\|\s*(ba)?sh/, reason: "Piping remote script to shell" },
	{ pattern: /git\s+push\s+.*--force/, reason: "Force push — may overwrite remote history" },
	{ pattern: /git\s+reset\s+--hard/, reason: "Hard reset — may lose uncommitted changes" },
	{ pattern: /npm\s+publish/, reason: "Publishing to npm registry" },
	{ pattern: /docker\s+system\s+prune/, reason: "Docker system prune — removes all unused data" },
];

// ═══════════════════════════════════════════════════════════════════════════
// Extension
// ═══════════════════════════════════════════════════════════════════════════

export default function (pi: ExtensionAPI) {
	let purpose: string | undefined;
	let activePreset: AgentPreset = AGENT_PRESETS[1]; // Default to "Explain Like I'm 5" for beginners
	let activeCtx: ExtensionContext | undefined;
	const toolCounts: Record<string, number> = {};
	const bookmarks: { timestamp: string; note: string }[] = [];
	let lastFileChange: { tool: string; path: string } | null = null;
	let toolRunsSinceLastTip = 0;

	// ── Tool tracking + contextual tips ───────────────────────────────
	pi.on("tool_execution_end", async (event) => {
		toolCounts[event.toolName] = (toolCounts[event.toolName] || 0) + 1;

		// Show a helpful hint every 5 tool runs
		toolRunsSinceLastTip++;
		if (activeCtx && toolRunsSinceLastTip >= 5) {
			toolRunsSinceLastTip = 0;
			const tips = [
				"💡 Confused? Type /explain and the AI will break down what just happened.",
				"💡 Want to save your progress? Type /bookmark to mark this moment.",
				"💡 Type /menu to see everything you can do.",
				"💡 Things going wrong? Type /stop to pause the AI immediately.",
				"💡 Type /undo to see how to reverse the last file change.",
				"💡 Type /status to see a summary of your whole session.",
			];
			const tip = tips[Math.floor(Math.random() * tips.length)];
			activeCtx.ui.notify(tip, "info");
		}
	});

	// ── Track file changes for /undo ──────────────────────────────────
	pi.on("tool_call", async (event, _ctx) => {
		if (isToolCallEventType("write", event) || isToolCallEventType("edit", event)) {
			lastFileChange = { tool: event.toolName, path: event.input.path };
		}
		return { block: false };
	});

	// ── Welcome Wizard ────────────────────────────────────────────────
	async function runWelcomeWizard(ctx: ExtensionContext) {
		// Step 1: Welcome
		ctx.ui.notify(
			"👋 Welcome to EasyMode!\n\n" +
			"This is your AI coding assistant. You type what you want\n" +
			"in plain English, and it writes the code for you.\n\n" +
			"Let's get you set up in 30 seconds...",
			"info"
		);

		// Step 2: Pick a personality
		const personalityOptions = AGENT_PRESETS.map((p) => `${p.emoji} ${p.name} — ${p.description}`);
		const personalityChoice = await ctx.ui.select(
			"Step 1 of 2: How should the AI talk to you?",
			personalityOptions
		);

		if (personalityChoice !== undefined) {
			const idx = personalityOptions.indexOf(personalityChoice);
			activePreset = AGENT_PRESETS[idx];
			ctx.ui.setStatus("easymode", `${activePreset.emoji} ${activePreset.name}`);
			ctx.ui.notify(`Great choice! ${activePreset.emoji} ${activePreset.name} activated.`, "info");
		} else {
			ctx.ui.notify(`Using default: ${activePreset.emoji} ${activePreset.name}`, "info");
		}

		// Step 3: Set a goal
		const answer = await ctx.ui.input(
			"Step 2 of 2: What do you want to do today?",
			"Examples: 'Make a website', 'Fix the bug on line 42', 'Explain this code to me'"
		);

		if (answer && answer.trim()) {
			purpose = answer.trim();
			ctx.ui.notify(`🎯 Goal set: ${purpose}`, "info");
			setPurposeWidget(ctx);
		} else {
			ctx.ui.notify("No problem! You can set a goal anytime by typing /goal", "info");
		}

		// Step 4: Quick orientation
		ctx.ui.notify(
			"✅ You're all set! Here's what you need to know:\n\n" +
			"  📝 Just type what you want in plain English\n" +
			"  🟢 /menu    — see all available commands\n" +
			"  🛑 /stop    — stop the AI if it's doing something wrong\n" +
			"  ❓ /explain — ask the AI to explain what it just did\n\n" +
			"⚠️ The AI will ask for your OK before doing anything dangerous.\n\n" +
			"Go ahead — type your first message! 🚀",
			"info"
		);
	}

	// ── Session start ─────────────────────────────────────────────────
	pi.on("session_start", async (_event, ctx) => {
		applyExtensionDefaults(import.meta.url, ctx);
		activeCtx = ctx;

		// Fire-and-forget — don't block TUI startup
		void runWelcomeWizard(ctx);

		// Footer
		ctx.ui.setFooter((tui, theme, footerData) => {
			const unsub = footerData.onBranchChange(() => tui.requestRender());

			return {
				dispose: unsub,
				invalidate() {},
				render(width: number): string[] {
					// Accumulate tokens + cost
					let tokIn = 0, tokOut = 0, cost = 0;
					for (const entry of ctx.sessionManager.getBranch()) {
						if (entry.type === "message" && entry.message.role === "assistant") {
							const m = entry.message as AssistantMessage;
							tokIn += m.usage.input;
							tokOut += m.usage.output;
							cost += m.usage.cost.total;
						}
					}

					const fmt = (n: number) => n < 1000 ? `${n}` : `${(n / 1000).toFixed(1)}k`;
					const model = ctx.model?.id || "no-model";
					const dir = basename(ctx.cwd);
					const branch = footerData.getGitBranch();

					// Context bar
					const usage = ctx.getContextUsage();
					const pct = usage?.percent ?? 0;
					const filled = Math.round(pct / 10);
					const bar = "█".repeat(filled) + "░".repeat(10 - filled);

					// Line 1: model + context + agent + cost
					const l1Left =
						theme.fg("dim", ` ${model} `) +
						(pct < 70 ? theme.fg("success", bar) : pct < 90 ? theme.fg("warning", bar) : theme.fg("error", bar)) +
						theme.fg("dim", ` ${Math.round(pct)}%  `) +
						theme.fg("accent", `${activePreset.emoji} ${activePreset.name}`);

					const l1Right =
						theme.fg("success", fmt(tokIn)) +
						theme.fg("dim", "↓ ") +
						theme.fg("accent", fmt(tokOut)) +
						theme.fg("dim", "↑ ") +
						theme.fg("warning", `$${cost.toFixed(4)}`) +
						theme.fg("dim", " ");

					const pad1 = " ".repeat(Math.max(1, width - visibleWidth(l1Left) - visibleWidth(l1Right)));
					const line1 = truncateToWidth(l1Left + pad1 + l1Right, width, "");

					// Line 2: cwd + branch + tools
					const l2Left =
						theme.fg("dim", ` ${dir}`) +
						(branch
							? theme.fg("dim", " ") + theme.fg("warning", "(") + theme.fg("success", branch) + theme.fg("warning", ")")
							: "");

					const entries = Object.entries(toolCounts);
					const l2Right = entries.length === 0
						? theme.fg("dim", "ready ")
						: entries
							.map(([name, count]) => theme.fg("accent", name) + theme.fg("dim", ":") + theme.fg("success", `${count}`))
							.join(theme.fg("dim", " ")) + " ";

					const pad2 = " ".repeat(Math.max(1, width - visibleWidth(l2Left) - visibleWidth(l2Right)));
					const line2 = truncateToWidth(l2Left + pad2 + l2Right, width, "");

					return [line1, line2];
				},
			};
		});

		ctx.ui.setStatus("easymode", `${activePreset.emoji} ${activePreset.name}`);
	});

	pi.on("session_switch", async (_event, ctx) => { activeCtx = ctx; });

	// ── Safety guard ──────────────────────────────────────────────────
	pi.on("tool_call", async (event, ctx) => {
		if (isToolCallEventType("bash", event)) {
			const cmd = event.input.command;
			for (const { pattern, reason } of DANGEROUS_PATTERNS) {
				if (pattern.test(cmd)) {
					const confirmed = await ctx.ui.confirm(
						"⚠️ Safety Warning",
						`${reason}\n\nCommand: ${cmd}\n\nAre you sure you want to run this?`,
						{ timeout: 30000 }
					);
					if (!confirmed) {
						ctx.ui.notify(`🛡️ Blocked: ${reason}`, "warning");
						ctx.abort();
						return {
							block: true,
							reason: `🛑 BLOCKED by Safety Guard: ${reason}\n\nThe user chose not to run this command. Ask them what they'd like to do instead.`,
						};
					}
					break;
				}
			}
		}
		return { block: false };
	});

	// ── System prompt injection ───────────────────────────────────────
	pi.on("before_agent_start", async (event) => {
		let extra = "";
		if (activePreset.systemPrompt) {
			extra += `\n\n<agent-preset name="${activePreset.name}">\n${activePreset.systemPrompt}\n</agent-preset>`;
		}
		if (purpose) {
			extra += `\n\n<user-goal>\nThe user's goal for this session: ${purpose}\nKeep this goal in mind. If the conversation drifts, gently guide back.\n</user-goal>`;
		}
		if (!extra) return;
		return { systemPrompt: event.systemPrompt + extra };
	});

	// ── Helper ────────────────────────────────────────────────────────
	function setPurposeWidget(ctx: ExtensionContext) {
		ctx.ui.setWidget("purpose", () => ({
			render(width: number): string[] {
				const label = "  ✅ Working on: ";
				const content = purpose!;
				const line = truncateToWidth(label + content, width - 2, "…");
				return [
					" ".repeat(width),
					line + " ".repeat(Math.max(0, width - visibleWidth(line))),
					" ".repeat(width),
				];
			},
			invalidate() {},
		}));
	}

	// ═══════════════════════════════════════════════════════════════════
	// Commands
	// ═══════════════════════════════════════════════════════════════════

	pi.registerCommand("help", {
		description: "Show all EasyMode commands",
		handler: async (_args, ctx) => {
			ctx.ui.notify(
				"📖 EasyMode Commands:\n\n" +
				"  /menu         — 🟢 START HERE — pick a command from a list\n" +
				"  /help         — You're looking at it!\n" +
				"  /agent        — Switch AI personality (beginner, builder, reviewer...)\n" +
				"  /goal         — Set or change your session goal\n" +
				"  /stop         — Immediately stop the current AI action\n" +
				"  /explain      — Ask the AI to explain what it just did\n" +
				"  /bookmark     — Save the current moment with a note\n" +
				"  /bookmarks    — See all saved bookmarks\n" +
				"  /undo         — Show how to undo the last file change\n" +
				"  /status       — Show session overview (goal, agent, stats)\n" +
				"  /quickstart   — Re-run the setup wizard\n" +
				"\n💡 Tips:\n" +
				"  • Just type what you want in plain English — no special syntax needed\n" +
				"  • The bottom bar shows your context usage and cost\n" +
				"  • ⚠️ Dangerous commands always ask for your OK first",
				"info"
			);
		},
	});

	pi.registerCommand("menu", {
		description: "Pick a command from a visual menu",
		handler: async (_args, ctx) => {
			const menuItems = [
				"🎯 Set or change my goal",
				"🤖 Switch AI personality",
				"💡 Explain what just happened",
				"🔖 Save a bookmark",
				"📋 See all my bookmarks",
				"↩️  Undo the last file change",
				"📊 Show session status",
				"🛑 Stop the AI",
				"🔄 Re-run setup wizard",
				"📖 Show all commands (help)",
			];
			const choice = await ctx.ui.select("What would you like to do?", menuItems);
			if (choice === undefined) return;

			const idx = menuItems.indexOf(choice);
			switch (idx) {
				case 0: { // Goal
					const answer = await ctx.ui.input("🎯 What's your goal?", purpose || "e.g. Fix the login bug...");
					if (answer && answer.trim()) {
						purpose = answer.trim();
						ctx.ui.notify(`🎯 Goal updated: ${purpose}`, "info");
						setPurposeWidget(ctx);
					}
					return;
				}
				case 1: { // Agent
					const options = AGENT_PRESETS.map((p) => `${p.emoji} ${p.name} — ${p.description}`);
					const agentChoice = await ctx.ui.select("Select AI Personality", options);
					if (agentChoice !== undefined) {
						const agentIdx = options.indexOf(agentChoice);
						activePreset = AGENT_PRESETS[agentIdx];
						ctx.ui.setStatus("easymode", `${activePreset.emoji} ${activePreset.name}`);
						ctx.ui.notify(`Switched to: ${activePreset.emoji} ${activePreset.name}\n${activePreset.description}`, "info");
					}
					return;
				}
				case 2: // Explain
					pi.sendUserMessage("Please explain what you just did in simple terms that a beginner would understand. Use bullet points and avoid jargon. If you wrote code, explain what each part does.");
					return;
				case 3: { // Bookmark
					const note = await ctx.ui.input("🔖 Bookmark note", "e.g. Got login working, Before refactor...");
					if (note && note.trim()) {
						const ts = new Date().toLocaleTimeString();
						bookmarks.push({ timestamp: ts, note: note.trim() });
						pi.appendEntry("easymode-bookmarks", { timestamp: ts, note: note.trim() });
						ctx.ui.notify(`🔖 Saved: ${note.trim()} (${ts})`, "info");
					}
					return;
				}
				case 4: { // Bookmarks
					if (bookmarks.length === 0) return ctx.ui.notify("No bookmarks yet. Use /bookmark to save one.", "info");
					const list = bookmarks.map((b, i) => `  ${i + 1}. [${b.timestamp}] ${b.note}`).join("\n");
					return ctx.ui.notify(`🔖 Bookmarks:\n\n${list}`, "info");
				}
				case 5: { // Undo
					if (!lastFileChange) {
						return ctx.ui.notify("No file changes tracked yet.\n\n💡 You can also tell the AI: \"Please undo the last change\"", "info");
					}
					return ctx.ui.notify(
						`↩️ Last change: ${lastFileChange.tool} → ${lastFileChange.path}\n\n` +
						'Tell the AI: "Please revert the last change"\n' +
						`Or run: git checkout -- ${lastFileChange.path}`,
						"info"
					);
				}
				case 6: { // Status
					const usage = ctx.getContextUsage();
					const pct = usage?.percent ?? 0;
					let tokIn = 0, tokOut = 0, cost = 0;
					for (const entry of ctx.sessionManager.getBranch()) {
						if (entry.type === "message" && entry.message.role === "assistant") {
							const m = entry.message as AssistantMessage;
							tokIn += m.usage.input;
							tokOut += m.usage.output;
							cost += m.usage.cost.total;
						}
					}
					return ctx.ui.notify(
						`📋 Session Status\n\n` +
						`  🎯 Goal:    ${purpose || "(not set)"}\n` +
						`  🤖 Agent:   ${activePreset.emoji} ${activePreset.name}\n` +
						`  📊 Context: ${Math.round(pct)}% used\n` +
						`  💰 Cost:    $${cost.toFixed(4)}`,
						"info"
					);
				}
				case 7: // Stop
					ctx.abort();
					return ctx.ui.notify("🛑 Stopped.", "warning");
				case 8: // Quickstart
					await runWelcomeWizard(ctx);
					return;
				case 9: // Help
					return ctx.ui.notify(
						"📖 All commands start with / (slash):\n\n" +
						"  /menu  /goal  /agent  /explain  /bookmark\n" +
						"  /bookmarks  /undo  /status  /stop  /quickstart  /help\n\n" +
						"Or just type what you want in plain English!",
						"info"
					);
			}
		},
	});

	pi.registerCommand("quickstart", {
		description: "Re-run the welcome wizard",
		handler: async (_args, ctx) => {
			await runWelcomeWizard(ctx);
		},
	});

	pi.registerCommand("agent", {
		description: "Switch AI personality preset",
		handler: async (_args, ctx) => {
			const options = AGENT_PRESETS.map((p) => `${p.emoji} ${p.name} — ${p.description}`);
			const choice = await ctx.ui.select("Select AI Personality", options);
			if (choice === undefined) return;
			const idx = options.indexOf(choice);
			activePreset = AGENT_PRESETS[idx];
			ctx.ui.setStatus("easymode", `${activePreset.emoji} ${activePreset.name}`);
			ctx.ui.notify(`Switched to: ${activePreset.emoji} ${activePreset.name}\n${activePreset.description}`, "info");
		},
	});

	pi.registerCommand("goal", {
		description: "Set or change your session goal",
		handler: async (_args, ctx) => {
			const answer = await ctx.ui.input("🎯 What's your goal?", purpose || "e.g. Fix the login bug...");
			if (answer && answer.trim()) {
				purpose = answer.trim();
				ctx.ui.notify(`🎯 Goal updated: ${purpose}`, "info");
				setPurposeWidget(ctx);
			}
		},
	});

	pi.registerCommand("stop", {
		description: "Immediately stop the current AI action",
		handler: async (args, ctx) => {
			const reason = (args || "").trim();
			ctx.abort();
			ctx.ui.notify(reason ? `🛑 Stopped: ${reason}` : "🛑 Stopped.", "warning");
		},
	});

	pi.registerCommand("explain", {
		description: "Ask the AI to explain its last action in simple terms",
		handler: async (_args, _ctx) => {
			pi.sendUserMessage(
				"Please explain what you just did in simple terms that a beginner would understand. " +
				"Use bullet points and avoid jargon. If you wrote code, explain what each part does."
			);
		},
	});

	pi.registerCommand("bookmark", {
		description: "Save a bookmark with a note",
		handler: async (_args, ctx) => {
			const note = await ctx.ui.input("🔖 Bookmark note", "e.g. Got login working, Before refactor...");
			if (note && note.trim()) {
				const ts = new Date().toLocaleTimeString();
				bookmarks.push({ timestamp: ts, note: note.trim() });
				pi.appendEntry("easymode-bookmarks", { timestamp: ts, note: note.trim() });
				ctx.ui.notify(`🔖 Saved: ${note.trim()} (${ts})`, "info");
			}
		},
	});

	pi.registerCommand("bookmarks", {
		description: "Show all saved bookmarks",
		handler: async (_args, ctx) => {
			if (bookmarks.length === 0) {
				ctx.ui.notify("No bookmarks yet. Use /bookmark to save one.", "info");
				return;
			}
			const list = bookmarks.map((b, i) => `  ${i + 1}. [${b.timestamp}] ${b.note}`).join("\n");
			ctx.ui.notify(`🔖 Bookmarks:\n\n${list}`, "info");
		},
	});

	pi.registerCommand("undo", {
		description: "Show how to undo the last file change",
		handler: async (_args, ctx) => {
			if (!lastFileChange) {
				ctx.ui.notify(
					"No file changes tracked yet.\n\n" +
					"💡 General undo:\n" +
					"  git checkout -- <file>   revert to last commit\n" +
					"  git diff                 see what changed\n" +
					"  git stash                save & revert everything",
					"info"
				);
				return;
			}
			ctx.ui.notify(
				`↩️ Last change: ${lastFileChange.tool} → ${lastFileChange.path}\n\n` +
				"To undo:\n" +
				`  git checkout -- ${lastFileChange.path}\n\n` +
				"See diff:\n" +
				`  git diff ${lastFileChange.path}\n\n` +
				'Or tell the AI: "Please revert the last change"',
				"info"
			);
		},
	});

	pi.registerCommand("status", {
		description: "Show session overview",
		handler: async (_args, ctx) => {
			const usage = ctx.getContextUsage();
			const pct = usage?.percent ?? 0;
			let tokIn = 0, tokOut = 0, cost = 0;
			for (const entry of ctx.sessionManager.getBranch()) {
				if (entry.type === "message" && entry.message.role === "assistant") {
					const m = entry.message as AssistantMessage;
					tokIn += m.usage.input;
					tokOut += m.usage.output;
					cost += m.usage.cost.total;
				}
			}
			const entries = Object.entries(toolCounts);
			const toolSummary = entries.length === 0
				? "  None yet"
				: entries.map(([n, c]) => `  ${n}: ${c}`).join("\n");

			ctx.ui.notify(
				`📋 Session Status\n\n` +
				`  🎯 Goal:      ${purpose || "(not set — use /goal)"}\n` +
				`  🤖 Agent:     ${activePreset.emoji} ${activePreset.name}\n` +
				`  📊 Context:   ${Math.round(pct)}% used\n` +
				`  💰 Cost:      $${cost.toFixed(4)}\n` +
				`  📨 Tokens:    ${tokIn} in / ${tokOut} out\n` +
				`  🔖 Bookmarks: ${bookmarks.length}\n` +
				`\n🔧 Tools Used:\n${toolSummary}`,
				"info"
			);
		},
	});
}
