/**
 * Theme store — manages dynamic CSS variables for theme customization.
 * Applies primary_color, accent_color, font_family, border_radius
 * from system settings to CSS custom properties on :root.
 */

import { create } from 'zustand';

export interface ThemeConfig {
  primaryColor: string;
  accentColor: string;
  fontFamily: string;
  borderRadius: string;
  darkMode: boolean;
}

interface ThemeState extends ThemeConfig {
  setTheme: (config: Partial<ThemeConfig>) => void;
  toggleDarkMode: () => void;
  applyTheme: () => void;
  loadFromStorage: () => void;
  saveToStorage: () => void;
}

const DEFAULT_THEME: ThemeConfig = {
  primaryColor: '#2563eb',
  accentColor: '#d946ef',
  fontFamily: 'Inter',
  borderRadius: '0.5rem',
  darkMode: false,
};

/** Convert hex color to RGB values for Tailwind CSS variable injection */
function hexToRgb(hex: string): { r: number; g: number; b: number } | null {
  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
  return result
    ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16),
      }
    : null;
}

/** Generate a Tailwind-style color scale (50-900) from a base hex color */
function generateColorScale(hex: string): Record<string, string> {
  const rgb = hexToRgb(hex);
  if (!rgb) return {};

  // Mix with white for lighter shades, with black for darker
  const mix = (base: number, amount: number, target: number) =>
    Math.round(base + (target - base) * amount);

  const scales: Record<number, [number, number]> = {
    50: [0.95, 0],   // 95% white
    100: [0.90, 0],
    200: [0.80, 0],
    300: [0.60, 0],
    400: [0.30, 0],
    500: [0, 0],     // base color
    600: [0, 0.10],  // 10% black
    700: [0, 0.20],
    800: [0, 0.30],
    900: [0, 0.40],
  };

  const result: Record<string, string> = {};
  for (const [scale, [whiteAmt, blackAmt]] of Object.entries(scales)) {
    const r = whiteAmt > 0 ? mix(rgb.r, whiteAmt, 255) : mix(rgb.r, blackAmt, 0);
    const g = whiteAmt > 0 ? mix(rgb.g, whiteAmt, 255) : mix(rgb.g, blackAmt, 0);
    const b = whiteAmt > 0 ? mix(rgb.b, whiteAmt, 255) : mix(rgb.b, blackAmt, 0);
    result[scale] = `rgb(${r} ${g} ${b})`;
  }
  result.DEFAULT = hex;
  return result;
}

function applyCSSVariables(config: ThemeConfig) {
  const root = document.documentElement;

  // Apply primary color scale
  const primaryScale = generateColorScale(config.primaryColor);
  for (const [key, val] of Object.entries(primaryScale)) {
    root.style.setProperty(`--color-primary-${key.toLowerCase()}`, val);
  }

  // Apply accent color scale
  const accentScale = generateColorScale(config.accentColor);
  for (const [key, val] of Object.entries(accentScale)) {
    root.style.setProperty(`--color-accent-${key.toLowerCase()}`, val);
  }

  // Apply font family
  root.style.setProperty('--font-sans', `'${config.fontFamily}', system-ui, sans-serif`);

  // Apply border radius
  root.style.setProperty('--radius-md', config.borderRadius);

  // Apply dark mode
  if (config.darkMode) {
    root.classList.add('dark');
  } else {
    root.classList.remove('dark');
  }
}

const STORAGE_KEY = 'leocrm-theme';

export const useThemeStore = create<ThemeState>((set, get) => ({
  ...DEFAULT_THEME,

  setTheme: (config) => {
    set((state) => ({ ...state, ...config }));
    get().applyTheme();
    get().saveToStorage();
  },

  toggleDarkMode: () => {
    set((state) => ({ ...state, darkMode: !state.darkMode }));
    get().applyTheme();
    get().saveToStorage();
  },

  applyTheme: () => {
    const state = get();
    applyCSSVariables({
      primaryColor: state.primaryColor,
      accentColor: state.accentColor,
      fontFamily: state.fontFamily,
      borderRadius: state.borderRadius,
      darkMode: state.darkMode,
    });
  },

  loadFromStorage: () => {
    try {
      const stored = localStorage.getItem(STORAGE_KEY);
      if (stored) {
        const config = JSON.parse(stored) as Partial<ThemeConfig>;
        set((state) => ({ ...state, ...config }));
      }
    } catch {
      // ignore parse errors
    }
    get().applyTheme();
  },

  saveToStorage: () => {
    const state = get();
    const { setTheme, toggleDarkMode, applyTheme, loadFromStorage, saveToStorage, ...config } = state;
    localStorage.setItem(STORAGE_KEY, JSON.stringify(config));
  },
}));
