/**
 * Default ShadCN color variables mapping.
 *
 * These tokens are intentionally generic so they can be safely overridden per theme preset.
 * Every key corresponds to a CSS custom property used by the Tailwind + shadcn integration
 * defined in `src/index.css` – the runtime applies overrides directly to `document.documentElement.style`.
 */

export type ThemeTokenKey =
  | '--background'
  | '--foreground'
  | '--card'
  | '--card-foreground'
  | '--popover'
  | '--popover-foreground'
  | '--primary'
  | '--primary-foreground'
  | '--secondary'
  | '--secondary-foreground'
  | '--muted'
  | '--muted-foreground'
  | '--accent'
  | '--accent-foreground'
  | '--destructive'
  | '--border'
  | '--input'
  | '--ring'
  | '--chart-1'
  | '--chart-2'
  | '--chart-3'
  | '--chart-4'
  | '--chart-5'
  | '--sidebar'
  | '--sidebar-foreground'
  | '--sidebar-primary'
  | '--sidebar-primary-foreground'
  | '--sidebar-accent'
  | '--sidebar-accent-foreground'
  | '--sidebar-border'
  | '--sidebar-ring';

export type ThemeTokenMap = Record<ThemeTokenKey, string>;

export interface ThemePreset {
  name: string;
  description: string;
  isDark: boolean;
  colors: ThemeTokenMap;
}

/**
 * Canonical token names that appear inside the customizer UI.
 * The order mirrors the logical grouping in the Settings panel so the
 * rendered color grid feels predictable to the user.
 */
export const THEME_TOKEN_LABELS: { key: ThemeTokenKey; label: string }[] = [
  { key: '--background', label: 'Background' },
  { key: '--foreground', label: 'Foreground' },
  { key: '--primary', label: 'Primary' },
  { key: '--primary-foreground', label: 'Primary text' },
  { key: '--secondary', label: 'Secondary' },
  { key: '--secondary-foreground', label: 'Secondary text' },
  { key: '--muted', label: 'Muted' },
  { key: '--muted-foreground', label: 'Muted text' },
  { key: '--accent', label: 'Accent' },
  { key: '--accent-foreground', label: 'Accent text' },
  { key: '--destructive', label: 'Destructive' },
  { key: '--border', label: 'Border' },
  { key: '--input', label: 'Input' },
  { key: '--ring', label: 'Ring' },
  { key: '--card', label: 'Card' },
  { key: '--card-foreground', label: 'Card text' },
  { key: '--popover', label: 'Popover' },
  { key: '--popover-foreground', label: 'Popover text' },
  { key: '--chart-1', label: 'Chart 1' },
  { key: '--chart-2', label: 'Chart 2' },
  { key: '--chart-3', label: 'Chart 3' },
  { key: '--chart-4', label: 'Chart 4' },
  { key: '--chart-5', label: 'Chart 5' },
  { key: '--sidebar', label: 'Sidebar' },
  { key: '--sidebar-foreground', label: 'Sidebar text' },
  { key: '--sidebar-primary', label: 'Sidebar primary' },
  { key: '--sidebar-primary-foreground', label: 'Sidebar primary text' },
  { key: '--sidebar-accent', label: 'Sidebar accent' },
  { key: '--sidebar-accent-foreground', label: 'Sidebar accent text' },
  { key: '--sidebar-border', label: 'Sidebar border' },
  { key: '--sidebar-ring', label: 'Sidebar ring' },
];

/** Storage key used by `useThemeManager`. */
export const THEME_STORAGE_KEY = 'custom-theme-preset';

/** All available preset names – used by the Settings UI to render radio options. */
export const THEME_PRESET_NAMES = [
  'default',
  'ocean',
  'forest',
  'sunset',
  'high-contrast',
] as const;

export type PresetName = (typeof THEME_PRESET_NAMES)[number] | 'custom';

// ---------------------------------------------------------------------------
// Preset definitions
// ---------------------------------------------------------------------------

const defaultLight: ThemeTokenMap = {
  '--background': 'oklch(1 0 0)',
  '--foreground': 'oklch(0.145 0 0)',
  '--card': 'oklch(1 0 0)',
  '--card-foreground': 'oklch(0.145 0 0)',
  '--popover': 'oklch(1 0 0)',
  '--popover-foreground': 'oklch(0.145 0 0)',
  '--primary': 'oklch(0.205 0 0)',
  '--primary-foreground': 'oklch(0.985 0 0)',
  '--secondary': 'oklch(0.97 0 0)',
  '--secondary-foreground': 'oklch(0.205 0 0)',
  '--muted': 'oklch(0.97 0 0)',
  '--muted-foreground': 'oklch(0.556 0 0)',
  '--accent': 'oklch(0.97 0 0)',
  '--accent-foreground': 'oklch(0.205 0 0)',
  '--destructive': 'oklch(0.577 0.245 27.325)',
  '--border': 'oklch(0.922 0 0)',
  '--input': 'oklch(0.922 0 0)',
  '--ring': 'oklch(0.708 0 0)',
  '--chart-1': 'oklch(0.87 0 0)',
  '--chart-2': 'oklch(0.556 0 0)',
  '--chart-3': 'oklch(0.439 0 0)',
  '--chart-4': 'oklch(0.371 0 0)',
  '--chart-5': 'oklch(0.269 0 0)',
  '--sidebar': 'oklch(0.985 0 0)',
  '--sidebar-foreground': 'oklch(0.145 0 0)',
  '--sidebar-primary': 'oklch(0.205 0 0)',
  '--sidebar-primary-foreground': 'oklch(0.985 0 0)',
  '--sidebar-accent': 'oklch(0.97 0 0)',
  '--sidebar-accent-foreground': 'oklch(0.205 0 0)',
  '--sidebar-border': 'oklch(0.922 0 0)',
  '--sidebar-ring': 'oklch(0.708 0 0)',
};

const defaultDark: ThemeTokenMap = {
  '--background': 'oklch(0.145 0 0)',
  '--foreground': 'oklch(0.985 0 0)',
  '--card': 'oklch(0.205 0 0)',
  '--card-foreground': 'oklch(0.985 0 0)',
  '--popover': 'oklch(0.205 0 0)',
  '--popover-foreground': 'oklch(0.985 0 0)',
  '--primary': 'oklch(0.922 0 0)',
  '--primary-foreground': 'oklch(0.205 0 0)',
  '--secondary': 'oklch(0.269 0 0)',
  '--secondary-foreground': 'oklch(0.985 0 0)',
  '--muted': 'oklch(0.269 0 0)',
  '--muted-foreground': 'oklch(0.708 0 0)',
  '--accent': 'oklch(0.269 0 0)',
  '--accent-foreground': 'oklch(0.985 0 0)',
  '--destructive': 'oklch(0.704 0.191 22.216)',
  '--border': 'oklch(1 0 0 / 10%)',
  '--input': 'oklch(1 0 0 / 15%)',
  '--ring': 'oklch(0.556 0 0)',
  '--chart-1': 'oklch(0.87 0 0)',
  '--chart-2': 'oklch(0.556 0 0)',
  '--chart-3': 'oklch(0.439 0 0)',
  '--chart-4': 'oklch(0.371 0 0)',
  '--chart-5': 'oklch(0.269 0 0)',
  '--sidebar': 'oklch(0.205 0 0)',
  '--sidebar-foreground': 'oklch(0.985 0 0)',
  '--sidebar-primary': 'oklch(0.488 0.243 264.376)',
  '--sidebar-primary-foreground': 'oklch(0.985 0 0)',
  '--sidebar-accent': 'oklch(0.269 0 0)',
  '--sidebar-accent-foreground': 'oklch(0.985 0 0)',
  '--sidebar-border': 'oklch(1 0 0 / 10%)',
  '--sidebar-ring': 'oklch(0.556 0 0)',
};

const oceanLight: ThemeTokenMap = {
  ...defaultLight,
  '--primary': 'oklch(0.45 0.16 250)',
  '--primary-foreground': 'oklch(0.98 0 0)',
  '--secondary': 'oklch(0.96 0.02 220)',
  '--secondary-foreground': 'oklch(0.25 0.10 250)',
  '--accent': 'oklch(0.80 0.12 200)',
  '--accent-foreground': 'oklch(0.20 0.08 220)',
  '--ring': 'oklch(0.55 0.20 240)',
  '--sidebar-primary': 'oklch(0.50 0.18 240)',
};

const oceanDark: ThemeTokenMap = {
  ...defaultDark,
  '--primary': 'oklch(0.78 0.14 210)',
  '--primary-foreground': 'oklch(0.12 0.04 220)',
  '--secondary': 'oklch(0.24 0.06 220)',
  '--secondary-foreground': 'oklch(0.92 0.02 200)',
  '--accent': 'oklch(0.30 0.10 220)',
  '--accent-foreground': 'oklch(0.90 0.05 210)',
  '--ring': 'oklch(0.60 0.22 220)',
  '--sidebar-primary': 'oklch(0.72 0.18 210)',
};

const forestLight: ThemeTokenMap = {
  ...defaultLight,
  '--primary': 'oklch(0.42 0.15 155)',
  '--primary-foreground': 'oklch(0.98 0 0)',
  '--secondary': 'oklch(0.95 0.03 150)',
  '--secondary-foreground': 'oklch(0.22 0.08 160)',
  '--accent': 'oklch(0.78 0.13 140)',
  '--accent-foreground': 'oklch(0.18 0.06 155)',
  '--ring': 'oklch(0.55 0.18 155)',
  '--sidebar-primary': 'oklch(0.48 0.16 155)',
};

const forestDark: ThemeTokenMap = {
  ...defaultDark,
  '--primary': 'oklch(0.74 0.14 150)',
  '--primary-foreground': 'oklch(0.12 0.04 160)',
  '--secondary': 'oklch(0.22 0.05 155)',
  '--secondary-foreground': 'oklch(0.90 0.03 150)',
  '--accent': 'oklch(0.28 0.10 155)',
  '--accent-foreground': 'oklch(0.88 0.06 150)',
  '--ring': 'oklch(0.58 0.20 150)',
  '--sidebar-primary': 'oklch(0.70 0.18 150)',
};

const sunsetLight: ThemeTokenMap = {
  ...defaultLight,
  '--primary': 'oklch(0.55 0.22 30)',
  '--primary-foreground': 'oklch(0.98 0 0)',
  '--secondary': 'oklch(0.96 0.03 40)',
  '--secondary-foreground': 'oklch(0.28 0.10 35)',
  '--accent': 'oklch(0.82 0.14 60)',
  '--accent-foreground': 'oklch(0.20 0.08 30)',
  '--ring': 'oklch(0.62 0.22 30)',
  '--sidebar-primary': 'oklch(0.58 0.20 35)',
};

const sunsetDark: ThemeTokenMap = {
  ...defaultDark,
  '--primary': 'oklch(0.80 0.18 30)',
  '--primary-foreground': 'oklch(0.12 0.04 35)',
  '--secondary': 'oklch(0.25 0.06 35)',
  '--secondary-foreground': 'oklch(0.92 0.03 30)',
  '--accent': 'oklch(0.32 0.12 40)',
  '--accent-foreground': 'oklch(0.88 0.05 35)',
  '--ring': 'oklch(0.60 0.24 30)',
  '--sidebar-primary': 'oklch(0.72 0.20 30)',
};

const highContrastLight: ThemeTokenMap = {
  ...defaultLight,
  '--background': 'oklch(1 0 0)',
  '--foreground': 'oklch(0 0 0)',
  '--primary': 'oklch(0 0 0)',
  '--primary-foreground': 'oklch(1 0 0)',
  '--secondary': 'oklch(0.95 0 0)',
  '--secondary-foreground': 'oklch(0 0 0)',
  '--muted': 'oklch(0.92 0 0)',
  '--muted-foreground': 'oklch(0 0 0)',
  '--accent': 'oklch(0.95 0 0)',
  '--accent-foreground': 'oklch(0 0 0)',
  '--destructive': 'oklch(0.45 0.25 27)',
  '--border': 'oklch(0 0 0)',
  '--input': 'oklch(0 0 0)',
  '--ring': 'oklch(0 0 0)',
};

const highContrastDark: ThemeTokenMap = {
  ...defaultDark,
  '--background': 'oklch(0 0 0)',
  '--foreground': 'oklch(1 0 0)',
  '--primary': 'oklch(1 0 0)',
  '--primary-foreground': 'oklch(0 0 0)',
  '--secondary': 'oklch(0.15 0 0)',
  '--secondary-foreground': 'oklch(1 0 0)',
  '--muted': 'oklch(0.20 0 0)',
  '--muted-foreground': 'oklch(1 0 0)',
  '--accent': 'oklch(0.20 0 0)',
  '--accent-foreground': 'oklch(1 0 0)',
  '--destructive': 'oklch(0.72 0.22 22)',
  '--border': 'oklch(1 0 0)',
  '--input': 'oklch(1 0 0)',
  '--ring': 'oklch(1 0 0)',
};

export const THEME_TOKEN_KEYS = THEME_TOKEN_LABELS.map((t) => t.key);

export const THEME_PRESETS: Record<string, ThemePreset> = {
  default: {
    name: 'Default',
    description: 'Clean neutral palette – good for most interfaces.',
    isDark: false,
    colors: defaultLight,
  },
  'default-dark': {
    name: 'Default',
    description: 'Dark mode counterpart for the default palette.',
    isDark: true,
    colors: defaultDark,
  },
  ocean: {
    name: 'Ocean',
    description: 'Cool blues and teals – calming for data-heavy UIs.',
    isDark: false,
    colors: oceanLight,
  },
  'ocean-dark': {
    name: 'Ocean',
    description: 'Dark mode for the ocean palette.',
    isDark: true,
    colors: oceanDark,
  },
  forest: {
    name: 'Forest',
    description: 'Earth-tone greens – great for productivity tools.',
    isDark: false,
    colors: forestLight,
  },
  'forest-dark': {
    name: 'Forest',
    description: 'Dark mode for the forest palette.',
    isDark: true,
    colors: forestDark,
  },
  sunset: {
    name: 'Sunset',
    description: 'Warm oranges and ambers – energetic without being garish.',
    isDark: false,
    colors: sunsetLight,
  },
  'sunset-dark': {
    name: 'Sunset',
    description: 'Dark mode for the sunset palette.',
    isDark: true,
    colors: sunsetDark,
  },
  'high-contrast': {
    name: 'High contrast',
    description: 'Maximum readability – black on white with strong accents.',
    isDark: false,
    colors: highContrastLight,
  },
  'high-contrast-dark': {
    name: 'High contrast',
    description: 'Dark mode for the high-contrast palette.',
    isDark: true,
    colors: highContrastDark,
  },
};

/**
 * Resolve the canonical token map for a given preset name + mode pair.
 *
 * When the caller passes `'custom'` the helper returns `null` – the consumer
 * is expected to handle that case by reading the token overrides from
 * localStorage instead.
 */
export function resolvePresetTokens(presetName: string, isDark: boolean): ThemeTokenMap | null {
  if (presetName === 'custom') return null;
  const darkKey = `${presetName}-dark`;
  // For dark mode: prefer `presetName-dark`, fall back to light variant
  if (isDark && THEME_PRESETS[darkKey]) {
    return THEME_PRESETS[darkKey].colors;
  }
  return THEME_PRESETS[presetName]?.colors ?? null;
}

/** Type-safe version used by useThemeManager. */
export function getPresetColors(name: PresetName, isDark: boolean): ThemeTokenMap | null {
  return resolvePresetTokens(name, isDark);
}
