import type { GenerationOptions, ThemeProposal } from './types.js';
import { enforceContrast } from './contrast.js';

/**
 * Deterministic local "brand vibe → palette" generator. Maps prompt
 * keywords to a hand-curated palette family, then derives the rest of
 * the proposal from there.
 *
 * Wave 13.E.1. The default. Hosts can pass `opts.generate` to swap in
 * a real LLM (or a fancier embedding-based generator) — the contrast
 * enforcement (Wave 13.E.2) runs after either path.
 */
const PALETTES: Array<{
  test: RegExp;
  name: string;
  accent: string;
  surface: string;
  surfaceCard: string;
  surfaceMuted: string;
  textPrimary: string;
  textSecondary: string;
}> = [
  {
    test: /\b(midnight|noir|deep|dark|nocturne|raven|space)\b/i,
    name: 'midnight',
    accent: '#7c8cff',
    surface: '#0b0f1a',
    surfaceCard: '#131a2b',
    surfaceMuted: '#1c2440',
    textPrimary: '#e7ecff',
    textSecondary: '#9aa6cf',
  },
  {
    test: /\b(citrus|sunshine|sunrise|amber|warm|orange|honey|gold)\b/i,
    name: 'citrus',
    accent: '#ff8a00',
    surface: '#fff7eb',
    surfaceCard: '#ffffff',
    surfaceMuted: '#ffe0b8',
    textPrimary: '#3b2a05',
    textSecondary: '#7a5a18',
  },
  {
    test: /\b(forest|leaf|moss|botanical|sage|jungle|emerald|verdant)\b/i,
    name: 'forest',
    accent: '#10b981',
    surface: '#f0faf5',
    surfaceCard: '#ffffff',
    surfaceMuted: '#cce8d8',
    textPrimary: '#0b3a23',
    textSecondary: '#365c45',
  },
  {
    test: /\b(ocean|sea|wave|aqua|coastal|maritime|blue|sky)\b/i,
    name: 'ocean',
    accent: '#0ea5e9',
    surface: '#f0f8ff',
    surfaceCard: '#ffffff',
    surfaceMuted: '#cee5fb',
    textPrimary: '#0a2b45',
    textSecondary: '#3a5d7d',
  },
  {
    test: /\b(rose|blossom|peach|pink|romantic|gentle)\b/i,
    name: 'rose',
    accent: '#ec4899',
    surface: '#fff5fa',
    surfaceCard: '#ffffff',
    surfaceMuted: '#fbd5e6',
    textPrimary: '#46123a',
    textSecondary: '#7b3f6b',
  },
  {
    test: /\b(graphite|monochrome|brutalist|stark|grayscale|minimal)\b/i,
    name: 'graphite',
    accent: '#374151',
    surface: '#f5f6f8',
    surfaceCard: '#ffffff',
    surfaceMuted: '#dcdfe5',
    textPrimary: '#0d1219',
    textSecondary: '#4b5563',
  },
  {
    test: /\b(violet|purple|cosmos|cosmic|mystic|nebula|lavender)\b/i,
    name: 'violet',
    accent: '#8b5cf6',
    surface: '#faf7ff',
    surfaceCard: '#ffffff',
    surfaceMuted: '#e5d8ff',
    textPrimary: '#1f0d49',
    textSecondary: '#5a4690',
  },
];

const DEFAULT_PALETTE: ThemeProposal = {
  name: 'default',
  accent: '#6366f1',
  surface: '#ffffff',
  surfaceCard: '#ffffff',
  surfaceMuted: '#f5f5f8',
  textPrimary: '#0f172a',
  textSecondary: '#475569',
  success: '#10b981',
  warning: '#f59e0b',
  danger: '#ef4444',
  info: '#0ea5e9',
};

/**
 * Generate (and contrast-check) a theme from a brand prompt.
 *
 * Defaults to a local deterministic mapper; pass `opts.generate` to
 * swap in a real LLM. AA contrast is enforced by default; pass
 * `enforce: 'aaa'` to lock the higher tier, or `'off'` to disable.
 */
export async function generateThemeFromPrompt(
  prompt: string,
  opts: GenerationOptions = {},
): Promise<ThemeProposal> {
  const raw = await (opts.generate ? opts.generate(prompt) : localGenerate(prompt));
  const enforce = opts.enforce ?? 'aa';
  return enforce === 'off' ? raw : enforceContrast(raw, enforce);
}

/** Synchronous local generator — exposed for tests + previews. */
export function localGenerate(prompt: string): ThemeProposal {
  for (const p of PALETTES) {
    if (p.test.test(prompt)) {
      return {
        ...DEFAULT_PALETTE,
        name: p.name,
        accent: p.accent,
        surface: p.surface,
        surfaceCard: p.surfaceCard,
        surfaceMuted: p.surfaceMuted,
        textPrimary: p.textPrimary,
        textSecondary: p.textSecondary,
      };
    }
  }
  return { ...DEFAULT_PALETTE, name: 'default' };
}
