/**
 * Edit Session Extension
 *
 * Adds /edit-session command to open the current session JSONL in your default editor.
 *
 * Usage:
 *   /edit-session          - Open current session file in $EDITOR
 *
 * The editor is determined by $VISUAL, then $EDITOR, then falls back to 'vi'.
 */

import type { ExtensionAPI, ExtensionCommandContext } from "@mariozechner/pi-coding-agent";
import type { TUI, Theme, KeybindingsManager, Component } from "@mariozechner/pi-tui";
import { spawnSync } from "node:child_process";

export default function editSessionExtension(pi: ExtensionAPI) {

	pi.registerCommand("edit-session", {
		description: "Open session JSONL in default editor ($VISUAL/$EDITOR/vi)",
		handler: async (_args: string, ctx: ExtensionCommandContext) => {
			const sessionFile = ctx.sessionManager.getSessionFile();

			if (!sessionFile) {
				ctx.ui.notify("No session file (ephemeral mode)", "error");
				return;
			}

			const editorCmd = process.env.VISUAL || process.env.EDITOR;
			if (!editorCmd) {
				ctx.ui.notify("No editor configured. Set $VISUAL or $EDITOR.", "error");
				return;
			}

			// Factory function to create component and run editor
			const factory = (
				tui: TUI,
				_theme: Theme,
				_kb: KeybindingsManager,
				done: (result: void) => void
			): Component => {
				// Stop TUI to release terminal (same as Ctrl+G)
				tui.stop();

				// Split editor command to support args (e.g., "code --wait")
				const [editor, ...editorArgs] = editorCmd.split(" ");

				// Spawn editor synchronously with inherited stdio
				const result = spawnSync(editor, [...editorArgs, sessionFile], {
					stdio: "inherit",
					shell: process.platform === "win32",
				});

				// Restart TUI
				tui.start();
				// Force full re-render since external editor uses alternate screen
				tui.requestRender(true);

				if (result.status !== 0 && result.status !== null) {
					ctx.ui.notify(`Editor exited with code ${result.status}`, "warning");
				}

				done();

				// Return dummy component
				return createDummyComponent();
			};

			// Use ctx.ui.custom to get access to the TUI
			await ctx.ui.custom<void>(factory);

			// Signal that we're about to reload the session (so confirm-destructive skips)
			pi.events.emit("edit-session:reload");

			// Reload the session by switching to the same file (forces re-read from disk)
			ctx.ui.notify("Reloading session...", "info");
			const result = await ctx.switchSession(sessionFile);

			if (result.cancelled) {
				// If still cancelled (by another extension), just notify without warning
				ctx.ui.notify("Session reload skipped. Run /reload to apply changes.", "info");
			} else {
				ctx.ui.notify("Session reloaded with changes.", "info");
			}
		},
	});
}

function createDummyComponent(): Component {
	return {
		render: (_width: number): string[] => [],
		invalidate: (): void => {},
	};
}