// open-in-editor.ts
// DEV utility: open source file in local editor

import { spawn } from "node:child_process";
import fs from "node:fs";
import path from "node:path";

/* -------------------------------------------------------
 * Types
 * ----------------------------------------------------- */

export interface EditorOptions {
	line?: number;
	column?: number;
	editor?: "vscode" | "cursor" | "windsurf" | "antigravity" | "subl";
}

/* -------------------------------------------------------
 * Editor commands
 * ----------------------------------------------------- */

const EDITORS = {
	vscode: "code",
	cursor: "cursor",
	windsurf: "windsurf",
	antigravity: "antigravity",
	subl: "subl",
} as const;

const buildCommand = (
	editor: keyof typeof EDITORS,
	file: string,
	line = 1,
	column = 1,
): [string, ...string[]] => {
	const cmd = EDITORS[editor];
	const location = `${file}:${line}:${column}`;

	return editor === "subl" ? [cmd, location] : [cmd, "--goto", location];
};

/* -------------------------------------------------------
 * Main function
 * ----------------------------------------------------- */

export function openInEditor(
	filePath: string,
	options: EditorOptions = {},
): void {
	// Resolve path
	const absolutePath = path.isAbsolute(filePath)
		? filePath
		: path.join(process.cwd(), filePath);

	if (!fs.existsSync(absolutePath)) {
		console.error("[openInEditor] File not found:", absolutePath);
		return;
	}

	const { line, column, editor } = options;

	// Launch helper
	const launch = (editorKey: keyof typeof EDITORS) => {
		const [cmd, ...args] = buildCommand(editorKey, absolutePath, line, column);
		spawn(cmd, args, { stdio: "ignore", detached: true }).unref();
	};

	// 1. Explicit editor
	if (editor) {
		launch(editor);
		return;
	}

	// 2. ENV detection
	const envEditor = (
		process.env.VISUAL ||
		process.env.EDITOR ||
		""
	).toLowerCase();
	const detectedEditor = Object.keys(EDITORS).find((key) =>
		envEditor.includes(key),
	) as keyof typeof EDITORS | undefined;

	if (detectedEditor) {
		launch(detectedEditor);
		return;
	}

	// 3. Fallback priority
	const fallbackOrder: (keyof typeof EDITORS)[] = [
		"cursor",
		"windsurf",
		"vscode",
		"antigravity",
		"subl",
	];

	for (const editorKey of fallbackOrder) {
		try {
			launch(editorKey);
			return;
		} catch {}
	}

	console.error("[openInEditor] No supported editor detected");
}

/* -------------------------------------------------------
 * Usage
 * ----------------------------------------------------- */
/*
openInEditor("src/pages/dashboard/index.tsx", { line: 31, column: 5 })
openInEditor("src/app.tsx", { editor: "cursor" })
*/
