// src/services/brand/palette.ts
export type PaletteKey = "primary" | "secondary" | "accent" | "neutral" | "surface" | "text";

export type Palette = Record<PaletteKey, string>;

export type PalettePreset =
  | "warm"
  | "cool"
  | "earth"
  | "sepia"
  | "pastel"
  | "neon";

/** Quick random hex */
export function rollHex(): string {
  return `#${Math.floor(Math.random() * 0xffffff).toString(16).padStart(6, "0")}`;
}

/** Generic full roll (keeps neutrals if provided) */
export function rollAll(prev?: Palette): Palette {
  return {
    primary: rollHex(),
    secondary: rollHex(),
    accent: rollHex(),
    neutral: prev?.neutral ?? "#f3f4f6",
    surface: prev?.surface ?? "#ffffff",
    text: prev?.text ?? "#1f2937",
  };
}

export function rollOne(p: Palette, key: PaletteKey): Palette {
  return { ...p, [key]: rollHex() };
}

/* ----------------- PRESETS ----------------- */
/** Curated seed sets (primary, secondary, accent) with sensible defaults for neutral/surface/text */
const PRESET_SEEDS: Record<
  PalettePreset,
  { primary: string[]; secondary: string[]; accent: string[]; neutral: string; surface: string; text: string }
> = {
  warm: {
    primary: ["#d97706", "#ea580c", "#dc2626"], // amber/orange/red
    secondary: ["#b91c1c", "#c2410c", "#a16207"],
    accent: ["#f59e0b", "#fb7185", "#f97316"],
    neutral: "#f5f5f5",
    surface: "#ffffff",
    text: "#111827",
  },
  cool: {
    primary: ["#2563eb", "#0ea5e9", "#0891b2"], // blue/cyan/teal
    secondary: ["#1d4ed8", "#06b6d4", "#10b981"],
    accent: ["#60a5fa", "#22d3ee", "#34d399"],
    neutral: "#eef2f7",
    surface: "#ffffff",
    text: "#0f172a",
  },
  earth: {
    primary: ["#6b7280", "#4f46e5", "#92400e"].map(() => "#7c5e3a"), // force brown base
    secondary: ["#a16207", "#3f6212", "#5b3a29"],
    accent: ["#86efac", "#22c55e", "#65a30d"],
    neutral: "#f3f4f1",
    surface: "#ffffff",
    text: "#1f2937",
  },
  sepia: {
    primary: ["#b08968", "#a98467", "#7f5539"],
    secondary: ["#ddb892", "#e6ccb2", "#9c6644"],
    accent: ["#e3caa5", "#b08968", "#ffedd5"],
    neutral: "#f7efe7",
    surface: "#fffaf0",
    text: "#2b2b2b",
  },
  pastel: {
    primary: ["#93c5fd", "#c7d2fe", "#fbcfe8"],
    secondary: ["#a7f3d0", "#fde68a", "#fca5a5"],
    accent: ["#f5d0fe", "#bfdbfe", "#bbf7d0"],
    neutral: "#f8fafc",
    surface: "#ffffff",
    text: "#111827",
  },
  neon: {
    primary: ["#22d3ee", "#a3e635", "#f59e0b"],
    secondary: ["#f43f5e", "#8b5cf6", "#14b8a6"],
    accent: ["#f472b6", "#34d399", "#60a5fa"],
    neutral: "#0b1020",  // darker UI vibe
    surface: "#0f172a",
    text: "#f8fafc",
  },
};

function pick<T>(arr: T[]): T {
  return arr[Math.floor(Math.random() * arr.length)];
}

/** Create a palette from a preset (random pick within each family) */
export function makePresetPalette(preset: PalettePreset): Palette {
  const s = PRESET_SEEDS[preset];
  return {
    primary: pick(s.primary),
    secondary: pick(s.secondary),
    accent: pick(s.accent),
    neutral: s.neutral,
    surface: s.surface,
    text: s.text,
  };
}

/** Apply preset but respect locks: only update unlocked keys */
export function applyPresetToPalette(
  preset: PalettePreset,
  current: Palette,
  locks: Record<PaletteKey, boolean>
): Palette {
  const next = { ...current };
  const seed = makePresetPalette(preset);
  (Object.keys(seed) as PaletteKey[]).forEach((k) => {
    if (!locks[k]) next[k] = seed[k];
  });
  return next;
}

/** Re-roll within the chosen preset (keeps neutral/surface/text constants) */
export function rollWithinPreset(
  preset: PalettePreset,
  current: Palette,
  locks: Record<PaletteKey, boolean>
): Palette {
  const s = PRESET_SEEDS[preset];
  const next = { ...current };
  const maybeSet = (k: PaletteKey, pool?: string[]) => {
    if (locks[k]) return;
    if (!pool || pool.length === 0) return;
    next[k] = pick(pool);
  };
  maybeSet("primary", s.primary);
  maybeSet("secondary", s.secondary);
  maybeSet("accent", s.accent);
  // neutrals are fixed per preset for contrast; keep current if locked
  if (!locks.neutral) next.neutral = s.neutral;
  if (!locks.surface) next.surface = s.surface;
  if (!locks.text) next.text = s.text;
  return next;
}
