import {
  themeToCss,
  type PaletteSet,
  type ActiveSelection,
  type ColorTokens,
  type ShapeTokens,
} from '@platform-modules/ui-tokens/theme-engine';
import type { PaletteOption } from '@platform-modules/ui-primitives';
import type { ThemeMeta } from './theme-contract.js';

// Shape is mode-invariant in mod-cms — same radii/sizes/weights light & dark (mirrors base.css).
const SHAPE: ShapeTokens = {
  'radius-none': '0',
  'radius-sm': '0.125rem',
  'radius-md': '0.375rem',
  'radius-lg': '0.5rem',
  'radius-xl': '0.75rem',
  'radius-full': '9999px',
  'font-size-xs': '0.75rem',
  'font-size-sm': '0.875rem',
  'font-size-base': '1rem',
  'font-size-lg': '1.125rem',
  'font-size-xl': '1.25rem',
  'font-size-2xl': '1.5rem',
  'font-size-3xl': '1.875rem',
  'font-weight-normal': '400',
  'font-weight-medium': '500',
  'font-weight-semibold': '600',
  'font-weight-bold': '700',
};

// LIGHT — base.css neutral defaults; border-strong corrected #c4c4c4 -> #8e8e8e (WCAG 1.4.11, 3.0 vs bg/surface).
const LIGHT: ColorTokens = {
  fg: '#1a1a1a',
  'fg-muted': '#555555',
  'fg-subtle': '#888888',
  bg: '#ffffff',
  surface: '#f7f7f7',
  'surface-raised': '#ffffff',
  border: '#e2e2e2',
  'border-strong': '#8e8e8e',
  accent: '#3b5bdb',
  'accent-fg': '#ffffff',
  success: '#237a35',
  warning: '#b45309',
  danger: '#c92a2a',
  info: '#1971c2',
  'success-fg': '#ffffff',
  'warning-fg': '#ffffff',
  'danger-fg': '#ffffff',
  'info-fg': '#ffffff',
};

// DARK — theme.css overrides; corrected: border-strong #454853 -> #686b74; intent/accent -fg #ffffff -> #14151a
// (white-on-bright fills failed 4.5:1; dark ink on the kept-bright fills passes AND the bright fills still read
// as text on the dark bg — the only contrast-stable dual-role resolution, proven by validateContrast).
const DARK: ColorTokens = {
  fg: '#eceae3',
  'fg-muted': '#b3b1a8',
  'fg-subtle': '#7b7d87',
  bg: '#14151a',
  surface: '#1d1f25',
  'surface-raised': '#1f2126',
  border: '#2e3038',
  'border-strong': '#686b74',
  accent: '#5b8def',
  'accent-fg': '#14151a',
  success: '#3dba6a',
  warning: '#e0a030',
  danger: '#e85d6a',
  info: '#5b9fd4',
  'success-fg': '#14151a',
  'warning-fg': '#14151a',
  'danger-fg': '#14151a',
  'info-fg': '#14151a',
};

// SLATE_LIGHT / SLATE_DARK — AA-verified (validateContrast + 12:1 ink floor); transcribed verbatim from spec.
const SLATE_LIGHT: ColorTokens = {
  fg: '#0f172a',
  'fg-muted': '#475569',
  'fg-subtle': '#64748b',
  bg: '#ffffff',
  surface: '#f8fafc',
  'surface-raised': '#ffffff',
  border: '#e2e8f0',
  'border-strong': '#64748b',
  accent: '#0f766e',
  'accent-fg': '#ffffff',
  success: '#237a35',
  warning: '#b45309',
  danger: '#c92a2a',
  info: '#1971c2',
  'success-fg': '#ffffff',
  'warning-fg': '#ffffff',
  'danger-fg': '#ffffff',
  'info-fg': '#ffffff',
};

const SLATE_DARK: ColorTokens = {
  fg: '#e2e8f0',
  'fg-muted': '#cbd5e1',
  'fg-subtle': '#94a3b8',
  bg: '#0f172a',
  surface: '#162231',
  'surface-raised': '#1a2736',
  border: '#334155',
  'border-strong': '#94a3b8',
  accent: '#2dd4bf',
  'accent-fg': '#0f172a',
  success: '#3dba6a',
  warning: '#e0a030',
  danger: '#f87171',
  info: '#5b9fd4',
  'success-fg': '#0f172a',
  'warning-fg': '#0f172a',
  'danger-fg': '#0f172a',
  'info-fg': '#0f172a',
};

export const MOD_CMS_PALETTE_SET: PaletteSet = {
  id: 'mod-cms',
  name: 'mod-cms',
  defaultPaletteId: 'default',
  palettes: [
    { id: 'default', name: 'Default', colors: { light: LIGHT, dark: DARK } },
    { id: 'slate', name: 'Slate', colors: { light: SLATE_LIGHT, dark: SLATE_DARK } },
  ],
  shape: { light: SHAPE, dark: SHAPE },
};

export const PALETTES: { id: string; name: string }[] = MOD_CMS_PALETTE_SET.palettes.map((p) => ({
  id: p.id,
  name: p.name,
}));

export function paletteOptions(mode: 'light' | 'dark'): PaletteOption[] {
  return MOD_CMS_PALETTE_SET.palettes.map((p) => {
    const c = p.colors[mode];
    return {
      id: p.id,
      label: p.name,
      swatches: [c.bg, c.surface, c.accent, c.fg],
      preview: {
        bg: c.bg,
        surface: c.surface,
        fg: c.fg,
        fgMuted: c['fg-muted'],
        accent: c.accent,
        accentFg: c['accent-fg'],
        border: c.border,
      },
    };
  });
}

/**
 * PURE presentation-theme projection (id + name only — NO components). The admin picker
 * and parseActiveSelection consume this; the component bindings live in src/themes/registry.ts.
 * Each id here MUST equal a key in MOD_CMS_THEMES (the registry guard enforces parity).
 */
export const THEME_REGISTRY_META: readonly ThemeMeta[] = [
  { id: 'default', name: 'Default', desc: 'Clean and flexible' },
  { id: 'editorial', name: 'Editorial', desc: 'Long-form reading' },
  { id: 'magazine', name: 'Magazine', desc: 'Bold publication' },
  { id: 'blog', name: 'Blog', desc: 'Chronological feed' },
] as const;

export const DEFAULT_THEME_ID = 'default';

/** Precomputed once — static SSR token CSS for the theme. Inject in <head>. */
export const themeCss: string = themeToCss(MOD_CMS_PALETTE_SET);

export const DEFAULT_SELECTION: ActiveSelection = {
  themeId: DEFAULT_THEME_ID,
  paletteId: MOD_CMS_PALETTE_SET.defaultPaletteId,
  mode: 'light',
};

const MODES = new Set(['light', 'dark', 'system']);

/**
 * Resolve the stored `theme` setting to an ActiveSelection. ALWAYS resolves (the site must never
 * blank on a bad setting — availability Hard floor). Back-compat: the legacy value was the bare
 * string 'light'|'dark' (the old data-theme mode); map it onto the default theme+palette.
 */
export function parseActiveSelection(value: unknown): ActiveSelection {
  // Legacy string form.
  if (value === 'light' || value === 'dark') return { ...DEFAULT_SELECTION, mode: value };
  if (!value || typeof value !== 'object') return DEFAULT_SELECTION;

  const v = value as { themeId?: unknown; paletteId?: unknown; mode?: unknown };
  const themeId =
    typeof v.themeId === 'string' && THEME_REGISTRY_META.some((t) => t.id === v.themeId)
      ? v.themeId
      : DEFAULT_THEME_ID;
  const paletteId =
    typeof v.paletteId === 'string' && MOD_CMS_PALETTE_SET.palettes.some((p) => p.id === v.paletteId)
      ? v.paletteId
      : MOD_CMS_PALETTE_SET.defaultPaletteId;
  const mode =
    typeof v.mode === 'string' && MODES.has(v.mode)
      ? (v.mode as ActiveSelection['mode'])
      : DEFAULT_SELECTION.mode;
  return { themeId, paletteId, mode };
}
