import { create } from 'zustand';
import type { TileInfo } from '../types/assets';
import type { ClassSummary, MethodSummary, FlowNode } from '../types/scripts';
import type { GumpDrawList } from '../types/gump';

// ── Typography constants ──────────────────────────────────────────────────────

// 7 sizes; index 1 = 16px (the current/default size per spec)
export const FONT_SIZE_VALUES = [13, 16, 18, 20, 22, 24, 28] as const;

export interface FontFamilyOption {
  label: string;
  value: string;
}

export const FONT_FAMILY_OPTIONS: FontFamilyOption[] = [
  { label: 'EB Garamond (Default)', value: "'EB Garamond', Georgia, serif" },
  { label: 'Cinzel', value: "'Cinzel', serif" },
  { label: 'Georgia', value: 'Georgia, serif' },
  { label: 'Palatino', value: "'Palatino Linotype', Palatino, serif" },
  { label: 'System UI', value: 'system-ui, sans-serif' },
];

export const DEFAULT_FONT_FAMILY = FONT_FAMILY_OPTIONS[0].value;
export const DEFAULT_TEXT_COLOR = '#d4c49a';
export const DEFAULT_FONT_SIZE_INDEX_REAL = 1; // index 1 = 16px

// ── Color utilities ───────────────────────────────────────────────────────────

function hexToRgb(hex: string): [number, number, number] {
  const n = parseInt(hex.replace('#', ''), 16);
  return [(n >> 16) & 255, (n >> 8) & 255, n & 255];
}

function rgbToHex(r: number, g: number, b: number): string {
  return '#' + [r, g, b]
    .map((v) => Math.max(0, Math.min(255, Math.round(v))).toString(16).padStart(2, '0'))
    .join('');
}

/** Scale each channel by `factor` (0–2). Values above 255 are clamped. */
function scaleColor(hex: string, factor: number): string {
  const [r, g, b] = hexToRgb(hex);
  return rgbToHex(r * factor, g * factor, b * factor);
}

/**
 * Derive the full text-color palette from a single primary color.
 *
 * Relationships mirror the default palette ratios:
 *   primary  (#d4c49a) → 1.0×
 *   accent-gold-bright → ~1.08× (slightly brighter/warmer)
 *   accent-gold        → ~0.88×
 *   text-secondary     → ~0.54×
 *   text-muted         → ~0.29×
 */
function deriveColorPalette(primary: string) {
  return {
    '--text-primary':        primary,
    '--accent-gold-bright':  scaleColor(primary, 1.08),
    '--accent-gold':         scaleColor(primary, 0.88),
    '--text-secondary':      scaleColor(primary, 0.54),
    '--text-muted':          scaleColor(primary, 0.29),
  };
}

export function applyTypographyVars(fontFamily: string, fontSizeIndex: number, textColor: string) {
  const size = FONT_SIZE_VALUES[fontSizeIndex] ?? 16;
  const el = document.documentElement;

  el.style.setProperty('--font-family-body', fontFamily);
  el.style.setProperty('--font-size-base', `${size}px`);

  const palette = deriveColorPalette(textColor);
  for (const [prop, val] of Object.entries(palette)) {
    el.style.setProperty(prop, val);
  }
}

export type LeftPanelTab = 'scripts' | 'statics' | 'mobiles' | 'gumps';

export type CenterMode =
  | 'empty'
  | 'config'
  | 'asset_static'
  | 'asset_mobile'
  | 'script_class'
  | 'flow_method'
  | 'gump_render'
  | 'gump_image';

export interface GumpEntry {
  id: number;
  name: string;
  tags: string[];
}

export interface ScriptGumpEntry {
  class_name: string;
  file_path: string;
  tags: string[];
}

interface AppState {
  // Config
  uoRoot: string;
  servuoScripts: string;
  assetFormat: 'mul' | 'uop';
  isConfigured: boolean;
  setUoRoot: (p: string) => void;
  setServuoScripts: (p: string) => void;
  setAssetFormat: (f: 'mul' | 'uop') => void;
  setIsConfigured: (v: boolean) => void;

  // Typography
  fontFamily: string;
  fontSizeIndex: number;
  textColor: string;
  setFontFamily: (f: string) => void;
  setFontSizeIndex: (i: number) => void;
  setTextColor: (c: string) => void;

  // Navigation
  activeTab: LeftPanelTab;
  centerMode: CenterMode;
  setActiveTab: (tab: LeftPanelTab) => void;
  setCenterMode: (mode: CenterMode) => void;

  // Asset browser
  selectedTile: TileInfo | null;
  setSelectedTile: (tile: TileInfo | null) => void;

  // Script browser
  selectedClass: ClassSummary | null;
  setSelectedClass: (c: ClassSummary | null) => void;

  // Method / flow
  selectedMethod: MethodSummary | null;
  setSelectedMethod: (m: MethodSummary | null) => void;

  // Flow tree
  flowRoot: FlowNode | null;
  setFlowRoot: (node: FlowNode | null) => void;

  // Gump
  gumpDrawList: GumpDrawList | null;
  setGumpDrawList: (g: GumpDrawList | null) => void;

  // Gump browser (Phase 4)
  selectedGump: GumpEntry | null;
  setSelectedGump: (g: GumpEntry | null) => void;

  // Script gump browser
  selectedScriptGump: ScriptGumpEntry | null;
  setSelectedScriptGump: (g: ScriptGumpEntry | null) => void;

  // Fake data for dynamic gumps / flow conditions
  fakeData: Record<string, string>;
  setFakeData: (key: string, value: string) => void;
  clearFakeData: () => void;
}

export const useAppStore = create<AppState>((set) => ({
  uoRoot: '',
  servuoScripts: '',
  assetFormat: 'mul',
  isConfigured: false,
  setUoRoot: (p) => set({ uoRoot: p }),
  setServuoScripts: (p) => set({ servuoScripts: p }),
  setAssetFormat: (f) => set({ assetFormat: f }),
  setIsConfigured: (v) => set({ isConfigured: v }),

  fontFamily: DEFAULT_FONT_FAMILY,
  fontSizeIndex: DEFAULT_FONT_SIZE_INDEX_REAL,
  textColor: DEFAULT_TEXT_COLOR,
  setFontFamily: (f) => {
    set((s) => {
      applyTypographyVars(f, s.fontSizeIndex, s.textColor);
      return { fontFamily: f };
    });
  },
  setFontSizeIndex: (i) => {
    set((s) => {
      applyTypographyVars(s.fontFamily, i, s.textColor);
      return { fontSizeIndex: i };
    });
  },
  setTextColor: (c) => {
    set((s) => {
      applyTypographyVars(s.fontFamily, s.fontSizeIndex, c);
      return { textColor: c };
    });
  },

  activeTab: 'statics',
  centerMode: 'empty',
  setActiveTab: (tab) => set({ activeTab: tab }),
  setCenterMode: (mode) => set({ centerMode: mode }),

  selectedTile: null,
  setSelectedTile: (tile) => set({ selectedTile: tile }),

  selectedClass: null,
  setSelectedClass: (c) => set({ selectedClass: c, selectedMethod: null, flowRoot: null }),

  selectedMethod: null,
  setSelectedMethod: (m) => set({ selectedMethod: m }),

  flowRoot: null,
  setFlowRoot: (node) => set({ flowRoot: node }),

  gumpDrawList: null,
  setGumpDrawList: (g) => set({ gumpDrawList: g }),

  selectedGump: null,
  setSelectedGump: (g) => set({ selectedGump: g }),

  selectedScriptGump: null,
  setSelectedScriptGump: (g) => set({ selectedScriptGump: g }),

  fakeData: {},
  setFakeData: (key, value) =>
    set((s) => ({ fakeData: { ...s.fakeData, [key]: value } })),
  clearFakeData: () => set({ fakeData: {} }),
}));
