import { existsSync, readFileSync, writeFileSync } from "node:fs";
import {
	CmuxClient,
	clearCmuxSidebar,
	detectCmuxEnvironment,
	resolveCmuxConfig,
} from "./cmux/index.js";
import {
	ensurePreferencesFile,
	serializePreferencesToFrontmatter,
} from "./commands-prefs-wizard.js";
import { saveFile } from "./files.js";
import {
	getProjectSFPreferencesPath,
	loadEffectiveSFPreferences,
	loadProjectSFPreferences,
} from "./preferences.js";
/**
 * Auto-enable cmux in project preferences when detected but never configured.
 * Called at boot (before agent start) — no ExtensionCommandContext needed.
 * Returns true if preferences were written, false if skipped.
 */
export function autoEnableCmuxPreferences() {
	const path = getProjectSFPreferencesPath();
	if (!existsSync(path)) return false;
	const existing = loadProjectSFPreferences();
	const prefs = existing?.preferences
		? { ...existing.preferences }
		: { version: 1 };
	prefs.cmux = {
		enabled: true,
		notifications: true,
		sidebar: true,
		splits: false,
		browser: false,
		...(prefs.cmux ?? {}),
	};
	prefs.cmux.enabled = true;
	prefs.version = prefs.version || 1;
	const frontmatter = serializePreferencesToFrontmatter(prefs);
	let body =
		"\n# SF Skill Preferences\n\nSee `~/.sf/agent/extensions/sf/docs/preferences-reference.md` for full field documentation and examples.\n";
	const preserved = extractBodyAfterFrontmatter(readFileSync(path, "utf-8"));
	if (preserved) body = preserved;
	writeFileSync(path, `---\n${frontmatter}---${body}`, "utf-8");
	return true;
}
function extractBodyAfterFrontmatter(content) {
	const start = content.startsWith("---\n")
		? 4
		: content.startsWith("---\r\n")
			? 5
			: -1;
	if (start === -1) return null;
	const closingIdx = content.indexOf("\n---", start);
	if (closingIdx === -1) return null;
	const after = content.slice(closingIdx + 4);
	return after.trim() ? after : null;
}
async function writeProjectCmuxPreferences(ctx, updater) {
	const path = getProjectSFPreferencesPath();
	await ensurePreferencesFile(path, ctx, "project");
	const existing = loadProjectSFPreferences();
	const prefs = existing?.preferences
		? { ...existing.preferences }
		: { version: 1 };
	updater(prefs);
	prefs.version = prefs.version || 1;
	const frontmatter = serializePreferencesToFrontmatter(prefs);
	let body =
		"\n# SF Skill Preferences\n\nSee `~/.sf/agent/extensions/sf/docs/preferences-reference.md` for full field documentation and examples.\n";
	if (existsSync(path)) {
		const preserved = extractBodyAfterFrontmatter(readFileSync(path, "utf-8"));
		if (preserved) body = preserved;
	}
	await saveFile(path, `---\n${frontmatter}---${body}`);
	await ctx.waitForIdle();
	await ctx.reload();
}
function formatCmuxStatus() {
	const loaded = loadEffectiveSFPreferences();
	const detected = detectCmuxEnvironment();
	const resolved = resolveCmuxConfig(loaded?.preferences);
	const capabilities = new CmuxClient(resolved).getCapabilities();
	const accessMode =
		typeof capabilities?.mode === "string"
			? capabilities.mode
			: typeof capabilities?.access_mode === "string"
				? capabilities.access_mode
				: "unknown";
	const methods = Array.isArray(capabilities?.methods)
		? capabilities.methods.length
		: 0;
	return [
		"cmux status",
		"",
		`Detected: ${detected.available ? "yes" : "no"}`,
		`Enabled: ${resolved.enabled ? "yes" : "no"}`,
		`CLI available: ${detected.cliAvailable ? "yes" : "no"}`,
		`Socket: ${detected.socketPath}`,
		`Workspace: ${detected.workspaceId ?? "(none)"}`,
		`Surface: ${detected.surfaceId ?? "(none)"}`,
		`Features: notifications=${resolved.notifications ? "on" : "off"}, sidebar=${resolved.sidebar ? "on" : "off"}, splits=${resolved.splits ? "on" : "off"}, browser=${resolved.browser ? "on" : "off"}`,
		`Capabilities: access=${accessMode}, methods=${methods}`,
	].join("\n");
}
function ensureCmuxAvailableForEnable(ctx) {
	const detected = detectCmuxEnvironment();
	if (detected.available) return true;
	ctx.ui.notify(
		"cmux not detected. Install it from https://cmux.com and run sf inside a cmux terminal.",
		"warning",
	);
	return false;
}
export async function handleCmux(args, ctx) {
	const trimmed = args.trim();
	if (!trimmed || trimmed === "status") {
		ctx.ui.notify(formatCmuxStatus(), "info");
		return;
	}
	if (trimmed === "on") {
		if (!ensureCmuxAvailableForEnable(ctx)) return;
		await writeProjectCmuxPreferences(ctx, (prefs) => {
			prefs.cmux = {
				enabled: true,
				notifications: true,
				sidebar: true,
				splits: false,
				browser: false,
				...(prefs.cmux ?? {}),
			};
			prefs.cmux.enabled = true;
		});
		ctx.ui.notify("cmux integration enabled in project preferences.", "info");
		return;
	}
	if (trimmed === "off") {
		const effective = loadEffectiveSFPreferences()?.preferences;
		await writeProjectCmuxPreferences(ctx, (prefs) => {
			prefs.cmux = {
				...(prefs.cmux ?? {}),
				enabled: false,
			};
		});
		clearCmuxSidebar(effective);
		ctx.ui.notify("cmux integration disabled in project preferences.", "info");
		return;
	}
	const parts = trimmed.split(/\s+/);
	if (
		parts.length === 2 &&
		["notifications", "sidebar", "splits", "browser"].includes(parts[0]) &&
		["on", "off"].includes(parts[1])
	) {
		const feature = parts[0];
		const enabled = parts[1] === "on";
		if (enabled && !ensureCmuxAvailableForEnable(ctx)) return;
		await writeProjectCmuxPreferences(ctx, (prefs) => {
			const next = {
				...(prefs.cmux ?? {}),
			};
			next[feature] = enabled;
			if (enabled) next.enabled = true;
			prefs.cmux = next;
		});
		if (!enabled && feature === "sidebar") {
			clearCmuxSidebar(loadEffectiveSFPreferences()?.preferences);
		}
		const note =
			feature === "browser" && enabled
				? " Browser surfaces are still a follow-up path."
				: "";
		ctx.ui.notify(
			`cmux ${feature} ${enabled ? "enabled" : "disabled"}.${note}`,
			"info",
		);
		return;
	}
	ctx.ui.notify(
		"Usage: /cmux <status|on|off|notifications on|notifications off|sidebar on|sidebar off|splits on|splits off|browser on|browser off>",
		"info",
	);
}
