import { resolveStateDir } from "../config/paths-state.js";
import { init_paths } from "../config/paths.js";
import { palette } from "./theme/dark.js";
import { palette as palette$1 } from "./theme/light.js";
import { existsSync, readFileSync, readdirSync } from "node:fs";
import { join } from "node:path";
import chalk from "chalk";
//#region src/tui/theme-manager.ts
init_paths();
const XTERM_LEVELS = [
	0,
	95,
	135,
	175,
	215,
	255
];
const BUILTIN_THEMES = {
	dark: palette,
	light: palette$1
};
function channelToSrgb(value) {
	const normalized = value / 255;
	return normalized <= .03928 ? normalized / 12.92 : ((normalized + .055) / 1.055) ** 2.4;
}
function relativeLuminanceRgb(red, green, blue) {
	return .2126 * channelToSrgb(red) + .7152 * channelToSrgb(green) + .0722 * channelToSrgb(blue);
}
function relativeLuminanceHex(hex) {
	return relativeLuminanceRgb(Number.parseInt(hex.slice(1, 3), 16), Number.parseInt(hex.slice(3, 5), 16), Number.parseInt(hex.slice(5, 7), 16));
}
function contrastRatio(bgLuminance, fgHex) {
	const fgLuminance = relativeLuminanceHex(fgHex);
	const lighter = Math.max(bgLuminance, fgLuminance);
	const darker = Math.min(bgLuminance, fgLuminance);
	return (lighter + .05) / (darker + .05);
}
function detectLightBackground(env = process.env) {
	const explicit = (env.XOPC_THEME ?? "").toLowerCase().trim();
	if (explicit === "light") return true;
	if (explicit === "dark") return false;
	const colorfgbg = env.COLORFGBG;
	if (colorfgbg && colorfgbg.length <= 64) {
		const sep = colorfgbg.lastIndexOf(";");
		const bg = Number.parseInt(sep >= 0 ? colorfgbg.slice(sep + 1) : colorfgbg, 10);
		if (bg >= 0 && bg <= 255) {
			if (bg <= 15) return bg === 7 || bg === 15;
			if (bg >= 232) return bg >= 244;
			const cubeIndex = bg - 16;
			const bVal = XTERM_LEVELS[cubeIndex % 6];
			const gVal = XTERM_LEVELS[Math.floor(cubeIndex / 6) % 6];
			const rVal = XTERM_LEVELS[Math.floor(cubeIndex / 36)];
			const bgLum = relativeLuminanceRgb(rVal, gVal, bVal);
			return contrastRatio(bgLum, "#1d1d1f") >= contrastRatio(bgLum, "#f5f5f7");
		}
	}
	return false;
}
function resolveCustomThemesDir() {
	return join(resolveStateDir(), "themes");
}
function loadCustomThemePalette(name) {
	const path = join(resolveCustomThemesDir(), `${name}.json`);
	if (!existsSync(path)) return null;
	try {
		const parsed = JSON.parse(readFileSync(path, "utf8"));
		if (!parsed?.palette || typeof parsed.palette !== "object") return null;
		return parsed.palette;
	} catch {
		return null;
	}
}
function fg(hex) {
	return (text) => chalk.hex(hex)(text);
}
function bg(hex) {
	return (text) => chalk.bgHex(hex)(text);
}
function highlightCode(code, codeHex) {
	return code.split("\n").map((line) => fg(codeHex)(line));
}
function buildThemeExports(palette, lightMode) {
	const theme = {
		fg: (key, text) => fg(palette[key])(text),
		fgText: fg(palette.text),
		assistantText: (text) => text,
		dim: fg(palette.dim),
		accent: fg(palette.accent),
		accentSoft: fg(palette.accentSoft),
		success: fg(palette.success),
		error: fg(palette.error),
		header: (text) => chalk.bold(fg(palette.accent)(text)),
		system: fg(palette.systemText),
		userBg: bg(palette.userBg),
		userText: fg(palette.userText),
		toolTitle: fg(palette.toolTitle),
		toolOutput: fg(palette.toolOutput),
		toolPendingBg: bg(palette.toolPendingBg),
		toolSuccessBg: bg(palette.toolSuccessBg),
		toolErrorBg: bg(palette.toolErrorBg),
		border: fg(palette.border),
		bold: (text) => chalk.bold(text),
		italic: (text) => chalk.italic(text)
	};
	const markdownTheme = {
		heading: (text) => chalk.bold(fg(palette.accent)(text)),
		link: (text) => fg(palette.link)(text),
		linkUrl: (text) => chalk.dim(text),
		code: (text) => fg(palette.code)(text),
		codeBlock: (text) => fg(palette.code)(text),
		codeBlockBorder: (text) => fg(palette.codeBorder)(text),
		quote: (text) => fg(palette.quote)(text),
		quoteBorder: (text) => fg(palette.quoteBorder)(text),
		hr: (text) => fg(palette.border)(text),
		listBullet: (text) => fg(palette.accentSoft)(text),
		bold: (text) => chalk.bold(text),
		italic: (text) => chalk.italic(text),
		strikethrough: (text) => chalk.strikethrough(text),
		underline: (text) => chalk.underline(text),
		highlightCode: (code) => highlightCode(code, palette.code)
	};
	const selectListTheme = {
		selectedPrefix: (text) => fg(palette.accent)(text),
		selectedText: (text) => chalk.bold(fg(palette.accent)(text)),
		description: (text) => fg(palette.dim)(text),
		scrollInfo: (text) => fg(palette.dim)(text),
		noMatch: (text) => fg(palette.dim)(text)
	};
	return {
		palette,
		lightMode,
		theme,
		markdownTheme,
		selectListTheme,
		searchableSelectListTheme: {
			...selectListTheme,
			searchPrompt: (text) => fg(palette.dim)(text),
			searchInput: (text) => fg(palette.text)(text),
			matchHighlight: (text) => fg(palette.accentSoft)(text)
		},
		editorTheme: {
			borderColor: (text) => fg(palette.border)(text),
			selectList: selectListTheme
		}
	};
}
let activeThemeId = "auto";
let activeExports = buildThemeExports(detectLightBackground() ? BUILTIN_THEMES.light : BUILTIN_THEMES.dark, detectLightBackground());
function getActiveThemeId() {
	return activeThemeId;
}
function listAvailableThemeIds() {
	const ids = new Set([
		"auto",
		"dark",
		"light"
	]);
	const dir = resolveCustomThemesDir();
	if (existsSync(dir)) {
		for (const entry of readdirSync(dir, { withFileTypes: true })) if (entry.isFile() && entry.name.endsWith(".json")) ids.add(entry.name.replace(/\.json$/, ""));
	}
	return [...ids];
}
function resolveThemePalette(themeId, env = process.env) {
	const normalized = themeId.trim().toLowerCase() || "auto";
	if (normalized === "auto") {
		const light = detectLightBackground(env);
		return {
			palette: light ? BUILTIN_THEMES.light : BUILTIN_THEMES.dark,
			lightMode: light,
			resolvedId: light ? "light" : "dark"
		};
	}
	if (normalized === "dark" || normalized === "light") return {
		palette: BUILTIN_THEMES[normalized],
		lightMode: normalized === "light",
		resolvedId: normalized
	};
	const custom = loadCustomThemePalette(normalized);
	if (custom) return {
		palette: custom,
		lightMode: false,
		resolvedId: normalized
	};
	const light = detectLightBackground(env);
	return {
		palette: light ? BUILTIN_THEMES.light : BUILTIN_THEMES.dark,
		lightMode: light,
		resolvedId: light ? "light" : "dark"
	};
}
/** Apply theme by id (`auto`, `dark`, `light`, or custom name). Returns resolved palette id. */
function applyThemeById(themeId, env = process.env) {
	activeThemeId = themeId.trim() || "auto";
	const resolved = resolveThemePalette(activeThemeId, env);
	activeExports = buildThemeExports(resolved.palette, resolved.lightMode);
	return resolved.resolvedId;
}
function getThemeExports() {
	return activeExports;
}
function getThinkingBorderColor(level) {
	const palette = activeExports.palette;
	return fg(palette[(() => {
		switch ((level ?? "off").toLowerCase()) {
			case "minimal": return "thinkingMinimal";
			case "low": return "thinkingLow";
			case "medium": return "thinkingMedium";
			case "high": return "thinkingHigh";
			case "xhigh": return "thinkingXhigh";
			case "adaptive": return "thinkingAdaptive";
			default: return "thinkingOff";
		}
	})()]);
}
function getBashModeBorderColor() {
	return fg(activeExports.palette.bashMode);
}
function getBashExcludeBorderColor() {
	return fg(activeExports.palette.bashExclude);
}
function getDefaultEditorBorderColor() {
	return activeExports.editorTheme.borderColor;
}
function getCustomThemesDir() {
	return resolveCustomThemesDir();
}
/** Initialize theme from CLI flag, env, or settings id. */
function initTuiTheme(options) {
	const env = options?.env ?? process.env;
	const fromEnv = env.XOPC_THEME?.trim();
	return applyThemeById(options?.themeId?.trim() || fromEnv || "auto", env);
}
//#endregion
export { applyThemeById, getActiveThemeId, getBashExcludeBorderColor, getBashModeBorderColor, getCustomThemesDir, getDefaultEditorBorderColor, getThemeExports, getThinkingBorderColor, initTuiTheme, listAvailableThemeIds, resolveThemePalette };

//# sourceMappingURL=theme-manager.js.map