import type {
	BrowserSlashCommandDispatchResult,
	BrowserSlashCommandSurface,
} from "./browser-slash-command-dispatch";
import type {
	DoctorFixResult,
	DoctorReport,
	ForensicReport,
	SkillHealthReport,
} from "./diagnostics-types";
import type { GitSummaryResponse } from "./git-summary-contract";
import type {
	CaptureResolveResult,
	CapturesData,
	KnowledgeData,
} from "./knowledge-captures-types";
import type {
	CleanupData,
	ExportResult,
	HistoryData,
	HooksData,
	InspectData,
	SteerData,
	UndoInfo,
} from "./remaining-command-types";
import type {
	SessionBrowserNameFilter,
	SessionBrowserSession,
	SessionBrowserSortMode,
} from "./session-browser-contract";
import type { SettingsData } from "./settings-types";

export const COMMAND_SURFACE_THINKING_LEVELS = [
	"off",
	"minimal",
	"low",
	"medium",
	"high",
	"xhigh",
] as const;

export type CommandSurfaceThinkingLevel =
	(typeof COMMAND_SURFACE_THINKING_LEVELS)[number];
export type CommandSurfaceSection =
	| "general"
	| "model"
	| "thinking"
	| "queue"
	| "compaction"
	| "retry"
	| "session-behavior"
	| "recovery"
	| "auth"
	| "admin"
	| "git"
	| "resume"
	| "name"
	| "fork"
	| "session"
	| "compact"
	| "workspace"
	| "integrations"
	| "experimental"
	// SF subcommand surfaces (S02)
	| "sf-status"
	| "sf-visualize"
	| "sf-forensics"
	| "sf-doctor"
	| "sf-skill-health"
	| "sf-knowledge"
	| "sf-capture"
	| "sf-triage"
	| "sf-quick"
	| "sf-history"
	| "sf-undo"
	| "sf-inspect"
	| "sf-prefs"
	| "sf-config"
	| "sf-hooks"
	| "sf-mode"
	| "sf-steer"
	| "sf-export"
	| "sf-cleanup"
	| "sf-queue";
export type CommandSurfaceSource = "slash" | "sidebar" | "surface";
export type CommandSurfacePendingAction =
	| "loading_models"
	| "set_model"
	| "set_thinking_level"
	| "set_steering_mode"
	| "set_follow_up_mode"
	| "set_auto_compaction"
	| "set_auto_retry"
	| "abort_retry"
	| "load_git_summary"
	| "load_recovery_diagnostics"
	| "load_session_browser"
	| "rename_session"
	| "save_api_key"
	| "start_provider_flow"
	| "submit_provider_flow_input"
	| "cancel_provider_flow"
	| "logout_provider"
	| "switch_session"
	| "load_fork_messages"
	| "fork_session"
	| "load_session_stats"
	| "export_html"
	| "compact_session";

export interface CommandSurfaceModelOption {
	provider: string;
	modelId: string;
	name?: string;
	reasoning: boolean;
	isCurrent: boolean;
}

export interface CommandSurfaceForkMessage {
	entryId: string;
	text: string;
}

export interface CommandSurfaceSessionStats {
	sessionFile: string | undefined;
	sessionId: string;
	userMessages: number;
	assistantMessages: number;
	toolCalls: number;
	toolResults: number;
	totalMessages: number;
	tokens: {
		input: number;
		output: number;
		cacheRead: number;
		cacheWrite: number;
		total: number;
	};
	cost: number;
}

export interface CommandSurfaceCompactionResult {
	summary: string;
	firstKeptEntryId: string;
	tokensBefore: number;
	details?: unknown;
}

export interface CommandSurfaceResumableSession {
	id: string;
	path: string;
	name?: string;
	isActive: boolean;
}

export interface CommandSurfaceSessionBrowserState {
	scope: "current_project" | null;
	projectCwd: string | null;
	projectSessionsDir: string | null;
	activeSessionPath: string | null;
	query: string;
	sortMode: SessionBrowserSortMode;
	nameFilter: SessionBrowserNameFilter;
	totalSessions: number;
	returnedSessions: number;
	sessions: SessionBrowserSession[];
	loaded: boolean;
	error: string | null;
}

export interface CommandSurfaceSessionMutationState {
	pending: boolean;
	sessionPath: string | null;
	result: string | null;
	error: string | null;
}

export interface CommandSurfaceSettingMutationState {
	pending: boolean;
	result: string | null;
	error: string | null;
}

export interface CommandSurfaceSettingsMutationState {
	steeringMode: CommandSurfaceSettingMutationState;
	followUpMode: CommandSurfaceSettingMutationState;
	autoCompaction: CommandSurfaceSettingMutationState;
	autoRetry: CommandSurfaceSettingMutationState;
	abortRetry: CommandSurfaceSettingMutationState;
}

export interface CommandSurfaceGitSummaryState {
	pending: boolean;
	loaded: boolean;
	result: GitSummaryResponse | null;
	error: string | null;
}

export type WorkspaceRecoverySummaryTone = "healthy" | "warning" | "danger";
export type WorkspaceRecoveryDiagnosticsStatus = "ready" | "unavailable";
export type WorkspaceRecoveryBrowserActionId =
	| "refresh_diagnostics"
	| "refresh_workspace"
	| "open_retry_controls"
	| "open_resume_controls"
	| "open_auth_controls";
export type CommandSurfaceRecoveryPhase =
	| "idle"
	| "loading"
	| "ready"
	| "unavailable"
	| "error";

export interface WorkspaceRecoveryBrowserAction {
	id: WorkspaceRecoveryBrowserActionId;
	label: string;
	detail: string;
	emphasis?: "primary" | "secondary" | "danger";
}

export interface WorkspaceRecoveryCommandSuggestion {
	label: string;
	command: string;
}

export interface WorkspaceRecoveryCodeSummary {
	code: string;
	count: number;
	label: string;
	severity: "info" | "warning" | "error";
}

export interface WorkspaceRecoveryIssueDigest {
	code: string;
	severity: "info" | "warning" | "error";
	scope: string;
	message: string;
	file?: string;
	suggestion?: string;
	unitId?: string;
}

export interface WorkspaceRecoveryDiagnostics {
	status: WorkspaceRecoveryDiagnosticsStatus;
	loadedAt: string;
	project: {
		cwd: string;
		activeScope: string | null;
		activeSessionPath: string | null;
		activeSessionId: string | null;
	};
	summary: {
		tone: WorkspaceRecoverySummaryTone;
		label: string;
		detail: string;
		validationCount: number;
		doctorIssueCount: number;
		lastFailurePhase: string | null;
		currentUnitId: string | null;
		retryAttempt: number;
		retryInProgress: boolean;
		compactionActive: boolean;
	};
	bridge: {
		phase: string;
		retry: {
			enabled: boolean;
			inProgress: boolean;
			attempt: number;
			label: string;
		};
		compaction: {
			active: boolean;
			label: string;
		};
		lastFailure: {
			message: string;
			phase: string;
			at: string;
			commandType: string | null;
			afterSessionAttachment: boolean;
		} | null;
		authRefresh: {
			phase: string;
			error: string | null;
			label: string;
		};
	};
	validation: {
		total: number;
		bySeverity: {
			errors: number;
			warnings: number;
			infos: number;
		};
		codes: WorkspaceRecoveryCodeSummary[];
		topIssues: WorkspaceRecoveryIssueDigest[];
	};
	doctor: {
		scope: string | null;
		total: number;
		errors: number;
		warnings: number;
		infos: number;
		fixable: number;
		codes: Array<{ code: string; count: number }>;
		topIssues: WorkspaceRecoveryIssueDigest[];
	};
	interruptedRun: {
		available: boolean;
		detected: boolean;
		label: string;
		detail: string;
		unit: {
			type: string;
			id: string;
		} | null;
		counts: {
			toolCalls: number;
			filesWritten: number;
			commandsRun: number;
			errors: number;
		};
		gitChangesDetected: boolean;
		lastError: string | null;
	};
	actions: {
		browser: WorkspaceRecoveryBrowserAction[];
		commands: WorkspaceRecoveryCommandSuggestion[];
	};
}

export interface CommandSurfaceRecoveryState {
	phase: CommandSurfaceRecoveryPhase;
	pending: boolean;
	loaded: boolean;
	stale: boolean;
	diagnostics: WorkspaceRecoveryDiagnostics | null;
	error: string | null;
	lastLoadedAt: string | null;
	lastInvalidatedAt: string | null;
	lastFailureAt: string | null;
}

export interface WorkspaceRecoverySummary {
	visible: boolean;
	tone: WorkspaceRecoverySummaryTone;
	label: string;
	detail: string;
	validationCount: number;
	retryInProgress: boolean;
	retryAttempt: number;
	autoRetryEnabled: boolean;
	isCompacting: boolean;
	currentUnitId: string | null;
	freshness: "idle" | "fresh" | "stale" | "error";
	entrypointLabel: string;
	lastError: {
		message: string;
		phase: string;
		at: string;
	} | null;
}

export type CommandSurfaceTarget =
	| { kind: "settings"; section: CommandSurfaceSection }
	| { kind: "model"; provider?: string; modelId?: string; query?: string }
	| { kind: "thinking"; level: CommandSurfaceThinkingLevel }
	| { kind: "auth"; providerId?: string; intent: "login" | "logout" | "manage" }
	| { kind: "resume"; sessionPath?: string }
	| { kind: "name"; sessionPath?: string; name: string }
	| { kind: "fork"; entryId?: string }
	| { kind: "session"; outputPath?: string }
	| { kind: "compact"; customInstructions: string }
	| { kind: "sf"; surface: string; subcommand: string; args: string };

// ─── Diagnostics panel state ──────────────────────────────────────────────────

export type CommandSurfaceDiagnosticsPhase =
	| "idle"
	| "loading"
	| "loaded"
	| "error";

export interface CommandSurfaceDiagnosticsPhaseState<T> {
	phase: CommandSurfaceDiagnosticsPhase;
	data: T | null;
	error: string | null;
	lastLoadedAt: string | null;
}

export interface CommandSurfaceDoctorState
	extends CommandSurfaceDiagnosticsPhaseState<DoctorReport> {
	fixPending: boolean;
	lastFixResult: DoctorFixResult | null;
	lastFixError: string | null;
}

export interface CommandSurfaceDiagnosticsState {
	forensics: CommandSurfaceDiagnosticsPhaseState<ForensicReport>;
	doctor: CommandSurfaceDoctorState;
	skillHealth: CommandSurfaceDiagnosticsPhaseState<SkillHealthReport>;
}

export function createInitialDiagnosticsPhaseState<
	T,
>(): CommandSurfaceDiagnosticsPhaseState<T> {
	return { phase: "idle", data: null, error: null, lastLoadedAt: null };
}

export function createInitialDoctorState(): CommandSurfaceDoctorState {
	return {
		phase: "idle",
		data: null,
		error: null,
		lastLoadedAt: null,
		fixPending: false,
		lastFixResult: null,
		lastFixError: null,
	};
}

export function createInitialDiagnosticsState(): CommandSurfaceDiagnosticsState {
	return {
		forensics: createInitialDiagnosticsPhaseState<ForensicReport>(),
		doctor: createInitialDoctorState(),
		skillHealth: createInitialDiagnosticsPhaseState<SkillHealthReport>(),
	};
}

// ─── Knowledge/Captures panel state ──────────────────────────────────────────

export interface CommandSurfaceKnowledgeCapturesResolveState {
	pending: boolean;
	lastError: string | null;
	lastResult: CaptureResolveResult | null;
}

export interface CommandSurfaceKnowledgeCapturesState {
	knowledge: CommandSurfaceDiagnosticsPhaseState<KnowledgeData>;
	captures: CommandSurfaceDiagnosticsPhaseState<CapturesData>;
	resolveRequest: CommandSurfaceKnowledgeCapturesResolveState;
}

export function createInitialKnowledgeCapturesState(): CommandSurfaceKnowledgeCapturesState {
	return {
		knowledge: createInitialDiagnosticsPhaseState<KnowledgeData>(),
		captures: createInitialDiagnosticsPhaseState<CapturesData>(),
		resolveRequest: { pending: false, lastError: null, lastResult: null },
	};
}

// ─── Settings panel state ────────────────────────────────────────────────────

export type CommandSurfaceSettingsState =
	CommandSurfaceDiagnosticsPhaseState<SettingsData>;

export function createInitialSettingsState(): CommandSurfaceSettingsState {
	return createInitialDiagnosticsPhaseState<SettingsData>();
}

// ─── Remaining command surfaces state ────────────────────────────────────────

export interface CommandSurfaceRemainingState {
	history: CommandSurfaceDiagnosticsPhaseState<HistoryData>;
	inspect: CommandSurfaceDiagnosticsPhaseState<InspectData>;
	hooks: CommandSurfaceDiagnosticsPhaseState<HooksData>;
	exportData: CommandSurfaceDiagnosticsPhaseState<ExportResult>;
	undo: CommandSurfaceDiagnosticsPhaseState<UndoInfo>;
	cleanup: CommandSurfaceDiagnosticsPhaseState<CleanupData>;
	steer: CommandSurfaceDiagnosticsPhaseState<SteerData>;
}

export function createInitialRemainingState(): CommandSurfaceRemainingState {
	return {
		history: createInitialDiagnosticsPhaseState<HistoryData>(),
		inspect: createInitialDiagnosticsPhaseState<InspectData>(),
		hooks: createInitialDiagnosticsPhaseState<HooksData>(),
		exportData: createInitialDiagnosticsPhaseState<ExportResult>(),
		undo: createInitialDiagnosticsPhaseState<UndoInfo>(),
		cleanup: createInitialDiagnosticsPhaseState<CleanupData>(),
		steer: createInitialDiagnosticsPhaseState<SteerData>(),
	};
}

export interface WorkspaceCommandSurfaceState {
	open: boolean;
	activeSurface: BrowserSlashCommandSurface | null;
	source: CommandSurfaceSource | null;
	section: CommandSurfaceSection | null;
	args: string;
	pendingAction: CommandSurfacePendingAction | null;
	selectedTarget: CommandSurfaceTarget | null;
	lastError: string | null;
	lastResult: string | null;
	availableModels: CommandSurfaceModelOption[];
	forkMessages: CommandSurfaceForkMessage[];
	sessionStats: CommandSurfaceSessionStats | null;
	lastCompaction: CommandSurfaceCompactionResult | null;
	gitSummary: CommandSurfaceGitSummaryState;
	recovery: CommandSurfaceRecoveryState;
	diagnostics: CommandSurfaceDiagnosticsState;
	knowledgeCaptures: CommandSurfaceKnowledgeCapturesState;
	settingsData: CommandSurfaceSettingsState;
	remainingCommands: CommandSurfaceRemainingState;
	sessionBrowser: CommandSurfaceSessionBrowserState;
	resumeRequest: CommandSurfaceSessionMutationState;
	renameRequest: CommandSurfaceSessionMutationState;
	settingsRequests: CommandSurfaceSettingsMutationState;
}

export interface CommandSurfaceOpenContext {
	onboardingLocked?: boolean;
	currentModel?: { provider?: string; modelId?: string } | null;
	currentThinkingLevel?: string | null;
	preferredProviderId?: string | null;
	resumableSessions?: CommandSurfaceResumableSession[];
	currentSessionPath?: string | null;
	currentSessionName?: string | null;
	projectCwd?: string | null;
	projectSessionsDir?: string | null;
}

export interface CommandSurfaceOpenRequest extends CommandSurfaceOpenContext {
	surface: BrowserSlashCommandSurface;
	source: CommandSurfaceSource;
	args?: string;
	selectedTarget?: CommandSurfaceTarget | null;
}

export interface CommandSurfaceActionResult {
	action: CommandSurfacePendingAction;
	success: boolean;
	message: string;
	selectedTarget?: CommandSurfaceTarget | null;
	availableModels?: CommandSurfaceModelOption[];
	forkMessages?: CommandSurfaceForkMessage[];
	sessionStats?: CommandSurfaceSessionStats | null;
	lastCompaction?: CommandSurfaceCompactionResult | null;
	gitSummary?: CommandSurfaceGitSummaryState;
	recovery?: CommandSurfaceRecoveryState;
	sessionBrowser?: CommandSurfaceSessionBrowserState;
}

const AUTH_SURFACE_COMMANDS = new Set<BrowserSlashCommandSurface>([
	"settings",
	"login",
	"logout",
]);
const SETTINGS_MUTATION_ACTION_TO_REQUEST: Partial<
	Record<CommandSurfacePendingAction, keyof CommandSurfaceSettingsMutationState>
> = {
	set_steering_mode: "steeringMode",
	set_follow_up_mode: "followUpMode",
	set_auto_compaction: "autoCompaction",
	set_auto_retry: "autoRetry",
	abort_retry: "abortRetry",
};

function matchingSessionPath(
	sessions: CommandSurfaceResumableSession[] | undefined,
	query: string | undefined,
): string | undefined {
	if (!sessions?.length) return undefined;
	const normalizedQuery = query?.trim().toLowerCase();
	if (!normalizedQuery) {
		return (
			sessions.find((session) => !session.isActive)?.path ?? sessions[0]?.path
		);
	}

	const exactMatch = sessions.find((session) => {
		const values = [session.id, session.name, session.path]
			.filter(Boolean)
			.map((value) => value!.toLowerCase());
		return values.includes(normalizedQuery);
	});
	if (exactMatch) return exactMatch.path;

	return sessions.find((session) => {
		const values = [session.id, session.name, session.path]
			.filter(Boolean)
			.map((value) => value!.toLowerCase());
		return values.some((value) => value.includes(normalizedQuery));
	})?.path;
}

function createInitialCommandSurfaceSessionBrowserState(
	overrides: Partial<CommandSurfaceSessionBrowserState> = {},
): CommandSurfaceSessionBrowserState {
	return {
		scope: null,
		projectCwd: null,
		projectSessionsDir: null,
		activeSessionPath: null,
		query: "",
		sortMode: "threaded",
		nameFilter: "all",
		totalSessions: 0,
		returnedSessions: 0,
		sessions: [],
		loaded: false,
		error: null,
		...overrides,
	};
}

function createInitialCommandSurfaceSessionMutationState(): CommandSurfaceSessionMutationState {
	return {
		pending: false,
		sessionPath: null,
		result: null,
		error: null,
	};
}

function createInitialCommandSurfaceSettingMutationState(): CommandSurfaceSettingMutationState {
	return {
		pending: false,
		result: null,
		error: null,
	};
}

function createInitialCommandSurfaceSettingsMutationState(): CommandSurfaceSettingsMutationState {
	return {
		steeringMode: createInitialCommandSurfaceSettingMutationState(),
		followUpMode: createInitialCommandSurfaceSettingMutationState(),
		autoCompaction: createInitialCommandSurfaceSettingMutationState(),
		autoRetry: createInitialCommandSurfaceSettingMutationState(),
		abortRetry: createInitialCommandSurfaceSettingMutationState(),
	};
}

function createInitialCommandSurfaceGitSummaryState(): CommandSurfaceGitSummaryState {
	return {
		pending: false,
		loaded: false,
		result: null,
		error: null,
	};
}

export function createInitialCommandSurfaceRecoveryState(): CommandSurfaceRecoveryState {
	return {
		phase: "idle",
		pending: false,
		loaded: false,
		stale: false,
		diagnostics: null,
		error: null,
		lastLoadedAt: null,
		lastInvalidatedAt: null,
		lastFailureAt: null,
	};
}

function buildInitialSessionBrowserState(
	request: CommandSurfaceOpenRequest,
): CommandSurfaceSessionBrowserState {
	const initialQuery =
		request.surface === "resume" ? (request.args?.trim() ?? "") : "";
	return createInitialCommandSurfaceSessionBrowserState({
		activeSessionPath: request.currentSessionPath ?? null,
		projectCwd: request.projectCwd ?? null,
		projectSessionsDir: request.projectSessionsDir ?? null,
		query: initialQuery,
		sortMode: initialQuery ? "relevance" : "threaded",
	});
}

export function isCommandSurfaceThinkingLevel(
	value: string | null | undefined,
): value is CommandSurfaceThinkingLevel {
	return COMMAND_SURFACE_THINKING_LEVELS.includes(
		(value ?? "") as CommandSurfaceThinkingLevel,
	);
}

export function createInitialCommandSurfaceState(): WorkspaceCommandSurfaceState {
	return {
		open: false,
		activeSurface: null,
		source: null,
		section: null,
		args: "",
		pendingAction: null,
		selectedTarget: null,
		lastError: null,
		lastResult: null,
		availableModels: [],
		forkMessages: [],
		sessionStats: null,
		lastCompaction: null,
		gitSummary: createInitialCommandSurfaceGitSummaryState(),
		recovery: createInitialCommandSurfaceRecoveryState(),
		diagnostics: createInitialDiagnosticsState(),
		knowledgeCaptures: createInitialKnowledgeCapturesState(),
		settingsData: createInitialSettingsState(),
		remainingCommands: createInitialRemainingState(),
		sessionBrowser: createInitialCommandSurfaceSessionBrowserState(),
		resumeRequest: createInitialCommandSurfaceSessionMutationState(),
		renameRequest: createInitialCommandSurfaceSessionMutationState(),
		settingsRequests: createInitialCommandSurfaceSettingsMutationState(),
	};
}

export function commandSurfaceSectionForRequest(
	request: CommandSurfaceOpenRequest,
): CommandSurfaceSection | null {
	switch (request.surface) {
		case "model":
			return "model";
		case "thinking":
			return "thinking";
		case "settings":
			return request.onboardingLocked ? "auth" : "general";
		case "git":
			return "git";
		case "login":
		case "logout":
			return "auth";
		case "resume":
			return "resume";
		case "name":
			return "name";
		case "fork":
			return "fork";
		case "session":
		case "export":
			return "session";
		case "compact":
			return "compact";
		// SF subcommand surfaces (S02)
		case "sf-status":
			return "sf-status";
		case "sf-visualize":
			return "sf-visualize";
		case "sf-forensics":
			return "sf-forensics";
		case "sf-doctor":
			return "sf-doctor";
		case "sf-skill-health":
			return "sf-skill-health";
		case "sf-knowledge":
			return "sf-knowledge";
		case "sf-capture":
			return "sf-capture";
		case "sf-triage":
			return "sf-triage";
		case "sf-quick":
			return "sf-quick";
		case "sf-history":
			return "sf-history";
		case "sf-undo":
			return "sf-undo";
		case "sf-inspect":
			return "sf-inspect";
		case "sf-prefs":
			return "sf-prefs";
		case "sf-config":
			return "sf-config";
		case "sf-hooks":
			return "sf-hooks";
		case "sf-mode":
			return "sf-mode";
		case "sf-steer":
			return "sf-steer";
		case "sf-export":
			return "sf-export";
		case "sf-cleanup":
			return "sf-cleanup";
		case "sf-queue":
			return "sf-queue";
		default:
			return null;
	}
}

function buildSettingsTarget(
	section: CommandSurfaceSection,
): CommandSurfaceTarget {
	return { kind: "settings", section };
}

function buildModelTarget(
	request: CommandSurfaceOpenRequest,
): CommandSurfaceTarget {
	const query = request.args?.trim() || undefined;
	return {
		kind: "model",
		provider: request.currentModel?.provider,
		modelId: request.currentModel?.modelId,
		query,
	};
}

function buildThinkingTarget(
	request: CommandSurfaceOpenRequest,
): CommandSurfaceTarget {
	const requestedLevel = request.args?.trim().toLowerCase() || "";
	const level = isCommandSurfaceThinkingLevel(requestedLevel)
		? requestedLevel
		: isCommandSurfaceThinkingLevel(request.currentThinkingLevel)
			? request.currentThinkingLevel
			: "off";

	return {
		kind: "thinking",
		level,
	};
}

function buildAuthTarget(
	request: CommandSurfaceOpenRequest,
): CommandSurfaceTarget {
	const requestedProviderId = request.args?.trim() || undefined;
	return {
		kind: "auth",
		providerId: requestedProviderId ?? request.preferredProviderId ?? undefined,
		intent:
			request.surface === "login"
				? "login"
				: request.surface === "logout"
					? "logout"
					: "manage",
	};
}

function buildResumeTarget(
	request: CommandSurfaceOpenRequest,
): Extract<CommandSurfaceTarget, { kind: "resume" }> {
	const selectedPath = matchingSessionPath(
		request.resumableSessions,
		request.args,
	);
	return {
		kind: "resume",
		sessionPath: selectedPath,
	};
}

function buildNameTarget(
	request: CommandSurfaceOpenRequest,
): CommandSurfaceTarget {
	const providedName = request.args?.trim();
	return {
		kind: "name",
		sessionPath: request.currentSessionPath ?? undefined,
		name:
			providedName !== undefined && providedName.length > 0
				? providedName
				: (request.currentSessionName?.trim() ?? ""),
	};
}

function buildForkTarget(
	request: CommandSurfaceOpenRequest,
): CommandSurfaceTarget {
	const entryId = request.args?.trim() || undefined;
	return {
		kind: "fork",
		entryId,
	};
}

function buildSessionTarget(
	request: CommandSurfaceOpenRequest,
): CommandSurfaceTarget {
	const outputPath = request.args?.trim() || undefined;
	return {
		kind: "session",
		outputPath,
	};
}

function buildCompactTarget(
	request: CommandSurfaceOpenRequest,
): CommandSurfaceTarget {
	return {
		kind: "compact",
		customInstructions: request.args?.trim() ?? "",
	};
}

export function buildCommandSurfaceTarget(
	request: CommandSurfaceOpenRequest,
): CommandSurfaceTarget | null {
	if (request.selectedTarget !== undefined) {
		return request.selectedTarget;
	}

	const section = commandSurfaceSectionForRequest(request);
	if (!section) return null;

	if (request.surface === "settings") {
		return buildSettingsTarget(section);
	}

	if (request.surface === "model") {
		return buildModelTarget(request);
	}

	if (request.surface === "thinking") {
		return buildThinkingTarget(request);
	}

	if (AUTH_SURFACE_COMMANDS.has(request.surface)) {
		return buildAuthTarget(request);
	}

	if (request.surface === "resume") {
		return buildResumeTarget(request);
	}

	if (request.surface === "name") {
		return buildNameTarget(request);
	}

	if (request.surface === "fork") {
		return buildForkTarget(request);
	}

	if (request.surface === "session" || request.surface === "export") {
		return buildSessionTarget(request);
	}

	if (request.surface === "compact") {
		return buildCompactTarget(request);
	}

	// SF subcommand surfaces — generic target (S02)
	if (request.surface?.startsWith("sf-")) {
		const subcommand = request.surface.slice(3); // "sf-forensics" -> "forensics"
		return {
			kind: "sf",
			surface: request.surface,
			subcommand,
			args: request.args ?? "",
		};
	}

	return buildSettingsTarget(section);
}

export function openCommandSurfaceState(
	current: WorkspaceCommandSurfaceState,
	request: CommandSurfaceOpenRequest,
): WorkspaceCommandSurfaceState {
	const section = commandSurfaceSectionForRequest(request);
	return {
		...current,
		open: true,
		activeSurface: request.surface,
		source: request.source,
		section,
		args: request.args?.trim() ?? "",
		pendingAction: null,
		selectedTarget: buildCommandSurfaceTarget(request),
		lastError: null,
		lastResult: null,
		sessionStats: null,
		forkMessages: [],
		lastCompaction: null,
		gitSummary: createInitialCommandSurfaceGitSummaryState(),
		recovery: createInitialCommandSurfaceRecoveryState(),
		diagnostics: createInitialDiagnosticsState(),
		knowledgeCaptures: createInitialKnowledgeCapturesState(),
		settingsData: createInitialSettingsState(),
		remainingCommands: createInitialRemainingState(),
		sessionBrowser: buildInitialSessionBrowserState(request),
		resumeRequest: createInitialCommandSurfaceSessionMutationState(),
		renameRequest: createInitialCommandSurfaceSessionMutationState(),
		settingsRequests: createInitialCommandSurfaceSettingsMutationState(),
	};
}

export function closeCommandSurfaceState(
	current: WorkspaceCommandSurfaceState,
): WorkspaceCommandSurfaceState {
	return {
		...current,
		open: false,
		pendingAction: null,
	};
}

export function setCommandSurfaceSection(
	current: WorkspaceCommandSurfaceState,
	section: CommandSurfaceSection,
	context: CommandSurfaceOpenContext = {},
): WorkspaceCommandSurfaceState {
	const request: CommandSurfaceOpenRequest = {
		surface: current.activeSurface ?? "settings",
		source: current.source ?? "surface",
		args: current.args,
		...context,
	};

	const currentSessionPath =
		current.selectedTarget?.kind === "resume"
			? current.selectedTarget.sessionPath
			: current.selectedTarget?.kind === "name"
				? current.selectedTarget.sessionPath
				: undefined;
	const currentDraftName =
		current.selectedTarget?.kind === "name"
			? current.selectedTarget.name
			: undefined;

	let selectedTarget: CommandSurfaceTarget | null = current.selectedTarget;
	if (section === "model") {
		selectedTarget = buildModelTarget(request);
	} else if (section === "thinking") {
		selectedTarget = buildThinkingTarget(request);
	} else if (
		section === "general" ||
		section === "session-behavior" ||
		section === "queue" ||
		section === "compaction" ||
		section === "retry" ||
		section === "recovery" ||
		section === "git" ||
		section === "admin"
	) {
		selectedTarget = buildSettingsTarget(section);
	} else if (section === "auth") {
		selectedTarget = buildAuthTarget({
			...request,
			surface:
				current.activeSurface === "logout"
					? "logout"
					: current.activeSurface === "login"
						? "login"
						: "settings",
		});
	} else if (section === "resume") {
		selectedTarget = {
			kind: "resume",
			sessionPath: currentSessionPath ?? buildResumeTarget(request).sessionPath,
		};
	} else if (section === "name") {
		selectedTarget = {
			kind: "name",
			sessionPath:
				currentSessionPath ?? request.currentSessionPath ?? undefined,
			name: currentDraftName ?? request.currentSessionName?.trim() ?? "",
		};
	} else if (section === "fork") {
		selectedTarget = buildForkTarget(request);
	} else if (section === "session") {
		selectedTarget = buildSessionTarget(request);
	} else if (section === "compact") {
		selectedTarget = buildCompactTarget(request);
	}

	return {
		...current,
		section,
		selectedTarget,
	};
}

export function selectCommandSurfaceStateTarget(
	current: WorkspaceCommandSurfaceState,
	target: CommandSurfaceTarget,
): WorkspaceCommandSurfaceState {
	const nextSection =
		target.kind === "settings"
			? target.section
			: target.kind === "model"
				? "model"
				: target.kind === "thinking"
					? "thinking"
					: target.kind === "auth"
						? "auth"
						: target.kind === "resume"
							? "resume"
							: target.kind === "name"
								? "name"
								: target.kind === "fork"
									? "fork"
									: target.kind === "session"
										? "session"
										: "compact";

	return {
		...current,
		section: nextSection,
		selectedTarget: target,
		lastError: null,
		lastResult: null,
	};
}

export function setCommandSurfacePending(
	current: WorkspaceCommandSurfaceState,
	action: CommandSurfacePendingAction,
	selectedTarget: CommandSurfaceTarget | null = current.selectedTarget,
): WorkspaceCommandSurfaceState {
	const nextResumeRequest =
		action === "switch_session"
			? {
					pending: true,
					sessionPath:
						selectedTarget?.kind === "resume"
							? (selectedTarget.sessionPath ?? null)
							: null,
					result: null,
					error: null,
				}
			: current.resumeRequest;

	const nextRenameRequest =
		action === "rename_session"
			? {
					pending: true,
					sessionPath:
						selectedTarget?.kind === "name"
							? (selectedTarget.sessionPath ?? null)
							: null,
					result: null,
					error: null,
				}
			: current.renameRequest;

	const settingsRequestKey = SETTINGS_MUTATION_ACTION_TO_REQUEST[action];
	const nextSettingsRequests = settingsRequestKey
		? {
				...current.settingsRequests,
				[settingsRequestKey]: {
					pending: true,
					result: null,
					error: null,
				},
			}
		: current.settingsRequests;

	return {
		...current,
		pendingAction: action,
		selectedTarget,
		lastError: null,
		lastResult: null,
		gitSummary:
			action === "load_git_summary"
				? {
						...current.gitSummary,
						pending: true,
						error: null,
					}
				: current.gitSummary,
		recovery:
			action === "load_recovery_diagnostics"
				? {
						...current.recovery,
						pending: true,
						error: null,
						phase: current.recovery.loaded ? current.recovery.phase : "loading",
					}
				: current.recovery,
		sessionBrowser:
			action === "load_session_browser"
				? {
						...current.sessionBrowser,
						error: null,
					}
				: current.sessionBrowser,
		resumeRequest: nextResumeRequest,
		renameRequest: nextRenameRequest,
		settingsRequests: nextSettingsRequests,
	};
}

export function applyCommandSurfaceActionResult(
	current: WorkspaceCommandSurfaceState,
	result: CommandSurfaceActionResult,
): WorkspaceCommandSurfaceState {
	const nextSelectedTarget =
		result.selectedTarget === undefined
			? current.selectedTarget
			: result.selectedTarget;
	const resumeSessionPath =
		(nextSelectedTarget?.kind === "resume"
			? nextSelectedTarget.sessionPath
			: undefined) ?? current.resumeRequest.sessionPath;
	const renameSessionPath =
		(nextSelectedTarget?.kind === "name"
			? nextSelectedTarget.sessionPath
			: undefined) ?? current.renameRequest.sessionPath;
	const settingsRequestKey = SETTINGS_MUTATION_ACTION_TO_REQUEST[result.action];
	const nextSettingsRequests = settingsRequestKey
		? {
				...current.settingsRequests,
				[settingsRequestKey]: {
					pending: false,
					result: result.success ? result.message : null,
					error: result.success ? null : result.message,
				},
			}
		: current.settingsRequests;

	return {
		...current,
		pendingAction: null,
		selectedTarget: nextSelectedTarget,
		availableModels: result.availableModels ?? current.availableModels,
		forkMessages: result.forkMessages ?? current.forkMessages,
		sessionStats:
			result.sessionStats === undefined
				? current.sessionStats
				: result.sessionStats,
		lastCompaction:
			result.lastCompaction === undefined
				? current.lastCompaction
				: result.lastCompaction,
		gitSummary:
			result.gitSummary === undefined
				? current.gitSummary
				: {
						...result.gitSummary,
						pending: false,
						loaded: result.gitSummary.loaded || result.success,
					},
		recovery: result.recovery ?? current.recovery,
		sessionBrowser: result.sessionBrowser ?? current.sessionBrowser,
		resumeRequest:
			result.action === "switch_session"
				? {
						pending: false,
						sessionPath: resumeSessionPath ?? null,
						result: result.success ? result.message : null,
						error: result.success ? null : result.message,
					}
				: current.resumeRequest,
		renameRequest:
			result.action === "rename_session"
				? {
						pending: false,
						sessionPath: renameSessionPath ?? null,
						result: result.success ? result.message : null,
						error: result.success ? null : result.message,
					}
				: current.renameRequest,
		settingsRequests: nextSettingsRequests,
		lastError: result.success ? null : result.message,
		lastResult: result.success ? result.message : null,
	};
}

export function surfaceOutcomeToOpenRequest(
	outcome: Extract<BrowserSlashCommandDispatchResult, { kind: "surface" }>,
	context: CommandSurfaceOpenContext = {},
): CommandSurfaceOpenRequest {
	return {
		surface: outcome.surface,
		source: "slash",
		args: outcome.args,
		...context,
	};
}
