import { writable, derived } from 'svelte/store';
import { browser } from '$app/environment';
import { type ThemeColorMap, defaultColorMap } from '$lib/components/tui/utils';

// Import theme JSON files
import archTheme from '$lib/assets/themes/arch.theme.json';
import catppuccinTheme from '$lib/assets/themes/catppuccin.theme.json';
import wintryTheme from '$lib/assets/themes/wintry.theme.json';
import roseTheme from '$lib/assets/themes/rose.theme.json';
import cerberusTheme from '$lib/assets/themes/cerberus.theme.json';

export type ColorTheme = 'arch' | 'catppuccin' | 'wintry' | 'rose' | 'cerberus';
export type Mode = 'dark' | 'light';

// Theme JSON structure
export interface ThemeJson {
	name: string;
	icon: string;
	dark: {
		colors: Record<string, string>;
		colorMap: ThemeColorMap;
	};
	light: {
		colors: Record<string, string>;
		colorMap: ThemeColorMap;
	};
}

export interface ThemeColors {
	primary: string;
	secondary: string;
	accent: string;
	background: string;
	backgroundLight: string;
	text: string;
	textMuted: string;
	border: string;
	terminal: string;
	terminalPrompt: string;
	terminalUser: string;
	terminalPath: string;
	colorMap: ThemeColorMap;
}

// Load themes from JSON files
const themes: Record<ColorTheme, ThemeJson> = {
	arch: archTheme as ThemeJson,
	catppuccin: catppuccinTheme as ThemeJson,
	wintry: wintryTheme as ThemeJson,
	rose: roseTheme as ThemeJson,
	cerberus: cerberusTheme as ThemeJson
};

// Export themes for external access
export { themes };

// Build theme colors from JSON - merges colors into colorMap so formatter can use both
function buildThemeColors(theme: ThemeJson, mode: Mode): ThemeColors {
	const modeData = theme[mode];
	// Merge: defaults -> theme palette -> theme colors (so text, primary, etc. are correct hex values)
	const mergedColorMap: ThemeColorMap = {
		...defaultColorMap,           // Fallback defaults (hex values)
		...(modeData.colorMap ?? {}), // Theme's color palette (hex values)
		// Also add theme colors so (&text), (&primary), etc. resolve to correct hex for this mode
		'text': modeData.colors.text,
		'textMuted': modeData.colors.textMuted,
		'primary': modeData.colors.primary,
		'secondary': modeData.colors.secondary,
		'accent': modeData.colors.accent,
		'background': modeData.colors.background,
		'backgroundLight': modeData.colors.backgroundLight,
		'border': modeData.colors.border,
		'terminal': modeData.colors.terminal,
		'terminalPrompt': modeData.colors.terminalPrompt,
		'terminalUser': modeData.colors.terminalUser,
		'terminalPath': modeData.colors.terminalPath,
		'muted': modeData.colors.textMuted, // alias
	};
	return {
		primary: modeData.colors.primary,
		secondary: modeData.colors.secondary,
		accent: modeData.colors.accent,
		background: modeData.colors.background,
		backgroundLight: modeData.colors.backgroundLight,
		text: modeData.colors.text,
		textMuted: modeData.colors.textMuted,
		border: modeData.colors.border,
		terminal: modeData.colors.terminal,
		terminalPrompt: modeData.colors.terminalPrompt,
		terminalUser: modeData.colors.terminalUser,
		terminalPath: modeData.colors.terminalPath,
		colorMap: mergedColorMap
	};
}

// Build the theme colors map from JSON themes
const themeColorsMap: Record<ColorTheme, { dark: ThemeColors; light: ThemeColors }> = 
	Object.fromEntries(
		Object.entries(themes).map(([key, theme]) => [
			key,
			{
				dark: buildThemeColors(theme, 'dark'),
				light: buildThemeColors(theme, 'light')
			}
		])
	) as Record<ColorTheme, { dark: ThemeColors; light: ThemeColors }>;

function getInitialMode(): Mode {
	if (browser) {
		const stored = localStorage.getItem('mode');
		if (stored === 'dark' || stored === 'light') return stored;
		return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
	}
	return 'dark';
}

function getInitialTheme(): ColorTheme {
	if (browser) {
		const stored = localStorage.getItem('colorTheme');
		if (stored && stored in themeColorsMap) return stored as ColorTheme;
	}
	return 'arch';
}

export const mode = writable<Mode>(getInitialMode());
export const colorTheme = writable<ColorTheme>(getInitialTheme());

export const themeColors = derived([mode, colorTheme], ([$mode, $colorTheme]) => {
	return themeColorsMap[$colorTheme][$mode];
});

// Subscribe to persist changes
if (browser) {
	mode.subscribe((value) => {
		localStorage.setItem('mode', value);
		document.documentElement.setAttribute('data-mode', value);
	});

	colorTheme.subscribe((value) => {
		localStorage.setItem('colorTheme', value);
		document.documentElement.setAttribute('data-theme', value);
	});
}

export function toggleMode() {
	mode.update((m) => (m === 'dark' ? 'light' : 'dark'));
}

export function setColorTheme(theme: ColorTheme) {
	colorTheme.set(theme);
}

export function getThemeIcon(theme: ColorTheme): string {
	switch (theme) {
		case 'arch': return 'mdi:arch';
		case 'catppuccin': return 'solar:cat-bold';
		case 'wintry': return 'mdi:snowflake';
		case 'rose': return 'mdi:flower-tulip';
		case 'cerberus': return 'iconoir:wolf-solid';
		default: return 'mdi:palette';
	}
}

// Generate theme options from loaded themes
export const themeOptions: { value: ColorTheme; label: string; icon: string }[] = 
	Object.entries(themes).map(([key, theme]) => ({
		value: key as ColorTheme,
		label: theme.name,
		icon: theme.icon
	}));
