/**
 * AI Studio design system — palette hooks.
 *
 * Architecture:
 *   CSS custom properties (index.css)  ← index.css :root / .dark  ← index.css @layer semantic
 *   ↑ read only                ← custom mode writes here
 *
 * In default mode the hook returns the CSS variable values (live, theme-aware).
 * In "custom" mode it returns the stored localStorage palette and also writes
 * those values to the DOM so they override the CSS layer.
 */

import { useEffect, useMemo, useState } from 'react';
import { useTheme } from '@/contexts';

// ─── Preset definitions ───────────────────────────────────────────────────────

export interface PaletteEntry {
  bg: string;         // page background
  bgSubtle: string;   // slightly elevated surface
  bgHover: string;    // hover state
  bgActive: string;   // active/pressed state
  border: string;     // default border
  borderFocus: string; // focus ring / active border
  borderMuted: string; // subtle dividers
  text: string;       // primary text
  textMuted: string;  // secondary / metadata
  textSubtle: string; // timestamps, hints
  accent: string;     // brand / action color
  accentHover: string;
  accentText: string; // text on accent bg
  icon: string;       // default icon color
  iconHover: string;  // icon hover color
  surface: string;    // card / elevated surface
  surface2: string;   // deeper surface
  online: string;     // online status dot
  away: string;       // away / idle dot
  offline: string;     // offline dot
  mentionBg: string;   // mention highlight bg (with alpha)
  mentionText: string; // mention highlight text
  msgBg: string;       // received message bubble bg
  msgOwnBg: string;    // own message bubble bg
  panelBg: string;     // sidebar / panel background
  badgeAi: string;     // tailwind classes for AI badge
  badgeRole: string;   // tailwind classes for role badge
}

export type ThemePresetId = 'default' | 'custom';

export interface ThemePreset {
  id: ThemePresetId;
  label: string;
  description: string;
  /** Pre-built palette object, or null = read from CSS vars (default mode) */
  palette: PaletteEntry | null;
}

// ─── Presets ──────────────────────────────────────────────────────────────────

export const THEME_PRESETS: ThemePreset[] = [
  {
    id: 'default',
    label: 'Default',
    description: 'Linear / Vercel inspired — neutral + single indigo accent',
    palette: null, // reads live from CSS vars
  },
];

/** Well-known CSS vars that map to PaletteEntry keys */
const PALETTE_VAR_MAP: Record<keyof PaletteEntry, string> = {
  bg:            '--bg',
  bgSubtle:      '--surface-2',
  bgHover:       '--surface-3',
  bgActive:      '--surface-3',
  border:        '--border',
  borderFocus:   '--ring',
  borderMuted:   '--border-2',
  text:          '--fg',
  textMuted:     '--fg-muted',
  textSubtle:    '--fg-subtle',
  accent:        '--accent',
  accentHover:   '--accent-hover',
  accentText:    '--accent-fg',
  icon:          '--fg-muted',
  iconHover:     '--fg',
  surface:       '--surface-2',
  surface2:      '--surface-3',
  online:        '--success',
  away:          '--warning',
  offline:       '--room-offline',
  mentionBg:     '--accent-subtle',
  mentionText:   '--accent',
  msgBg:         '--surface-2',
  msgOwnBg:      '--accent-subtle',
  panelBg:       '--sidebar-bg',
  badgeAi:       'bg-accent/10 text-accent font-medium',
  badgeRole:     'bg-muted text-muted-foreground font-medium',
};

/** Read a CSS custom property value from the DOM, fallback to a default */
function readCssVar(name: string, fallback: string): string {
  if (typeof document === 'undefined') return fallback;
  return getComputedStyle(document.documentElement)
    .getPropertyValue(name)
    .trim() || fallback;
}

// ─── Custom palette storage ───────────────────────────────────────────────────

const CUSTOM_KEY = 'theme-custom-palette';
const PRESET_KEY = 'theme-preset';

export function loadCustomPalette(): PaletteEntry | null {
  try {
    const raw = localStorage.getItem(CUSTOM_KEY);
    if (!raw) return null;
    return JSON.parse(raw) as PaletteEntry;
  } catch {
    return null;
  }
}

export function saveCustomPalette(palette: PaletteEntry) {
  localStorage.setItem(CUSTOM_KEY, JSON.stringify(palette));
}

export function clearCustomPalette() {
  localStorage.removeItem(CUSTOM_KEY);
  localStorage.setItem(PRESET_KEY, 'default');
}

export function loadActivePresetId(): ThemePresetId {
  return (localStorage.getItem(PRESET_KEY) as ThemePresetId) || 'default';
}

export function saveActivePresetId(id: ThemePresetId) {
  localStorage.setItem(PRESET_KEY, id);
  // Notify all useAIPalette hooks to re-read
  window.dispatchEvent(new CustomEvent('theme-preset-change', { detail: id }));
}

/**
 * Apply a custom palette to the DOM root so it overrides the CSS layer.
 * Only the keys present in PALETTE_VAR_MAP are written.
 */
export function applyPaletteToDOM(palette: PaletteEntry) {
  const root = document.documentElement;
  for (const [key, cssVar] of Object.entries(PALETTE_VAR_MAP)) {
    if (key === 'badgeAi' || key === 'badgeRole') continue; // class strings, skip
    root.style.setProperty(cssVar, (palette as unknown as Record<string, string>)[key]);
  }
}

/** Reset DOM overrides back to the CSS layer (removes custom inline styles) */
export function resetDOMFromPalette() {
  const root = document.documentElement;
  for (const cssVar of Object.values(PALETTE_VAR_MAP)) {
    if (cssVar === '--badge-ai' || cssVar === '--badge-role') continue;
    root.style.removeProperty(cssVar);
  }
}

// ─── Hook ────────────────────────────────────────────────────────────────────

export function useAIPalette(): PaletteEntry {
  const { resolvedTheme } = useTheme();
  const [customPalette, setCustomPalette] = useState<PaletteEntry | null>(
    loadCustomPalette,
  );
  const [activePresetId, setActivePresetId] = useState<ThemePresetId>(loadActivePresetId);

  // Re-read from localStorage when the custom palette changes
  // (e.g. after ThemeSwitcher saves a new custom palette)
  useEffect(() => {
    const onPresetChange = () => {
      setActivePresetId(loadActivePresetId());
      setCustomPalette(loadCustomPalette());
    };
    window.addEventListener('theme-preset-change', onPresetChange);
    return () => window.removeEventListener('theme-preset-change', onPresetChange);
  }, []);

  // ── Derive palette ──────────────────────────────────────────────────────

  if (activePresetId === 'custom' && customPalette) {
    // Custom mode: return the stored palette (DOM is already updated by the
    // ThemeSwitcher, but we also return it here so callers get the right values)
    return customPalette;
  }

  // Default mode: read live from CSS variables
  return useMemo<PaletteEntry>(() => {
    // re-compute when light/dark resolvedTheme changes
    void resolvedTheme;

    return {
      bg:           readCssVar('--bg',           '#ffffff'),
      bgSubtle:     readCssVar('--surface-2',    '#f9f9fa'),
      bgHover:      readCssVar('--surface-3',    '#f3f3f5'),
      bgActive:     readCssVar('--surface-3',    '#ebebef'),
      border:       readCssVar('--border',        '#e4e4e8'),
      borderFocus:  readCssVar('--ring',          '#1c7ded'),
      borderMuted:  readCssVar('--border-2',     '#eeeeef'),
      text:         readCssVar('--fg',           '#1f1f1f'),
      textMuted:    readCssVar('--fg-muted',     '#8a8a8f'),
      textSubtle:   readCssVar('--fg-subtle',    '#b8b8bd'),
      accent:       readCssVar('--accent',        '#1c7ded'),
      accentHover:  readCssVar('--accent-hover',  '#1a73d4'),
      accentText:   readCssVar('--accent-fg',    '#ffffff'),
      icon:         readCssVar('--fg-muted',      '#8a8a8f'),
      iconHover:    readCssVar('--fg',           '#5c5c62'),
      surface:      readCssVar('--surface-2',    '#f7f7f8'),
      surface2:     readCssVar('--surface-3',    '#eeeeef'),
      online:       readCssVar('--success',      '#22c55e'),
      away:         readCssVar('--warning',      '#f59e0b'),
      offline:      readCssVar('--room-offline',  '#d1d1d6'),
      mentionBg:    readCssVar('--accent-subtle', 'rgba(28,125,237,0.08)'),
      mentionText:  readCssVar('--accent',        '#1c7ded'),
      msgBg:        readCssVar('--surface-2',    '#f9f9fb'),
      msgOwnBg:     readCssVar('--accent-subtle', '#e8f0fe'),
      panelBg:      readCssVar('--sidebar-bg',   '#f9f9fa'),
      badgeAi:      'bg-accent/10 text-accent font-medium',
      badgeRole:    'bg-muted text-muted-foreground font-medium',
    };
  }, [resolvedTheme]);
}

/** Trigger a custom palette: saves to localStorage, applies to DOM, sets preset */
export function activateCustomPalette(palette: PaletteEntry) {
  saveCustomPalette(palette);
  saveActivePresetId('custom');
  applyPaletteToDOM(palette);
}

/** Reset back to the default CSS-layer theme */
export function deactivateCustomPalette() {
  clearCustomPalette();
  resetDOMFromPalette();
}
