/**
 * Dashboard theme model.
 *
 * Themes customise three orthogonal layers:
 *
 *   1. `palette`       — the 3-layer color triplet (background/midground/
 *                         foreground) + warm-glow + noise opacity. The
 *                         design-system cascade in `src/index.css` derives
 *                         every shadcn-compat token (card, muted, border,
 *                         primary, etc.) from this triplet via `color-mix()`.
 *   2. `typography`    — font families, base font size, line height,
 *                         letter spacing. An optional `fontUrl` is injected
 *                         as `<link rel="stylesheet">` so self-hosted and
 *                         Google/Bunny/etc-hosted fonts both work.
 *   3. `layout`        — corner radius and density (spacing multiplier).
 *
 * Plus an optional `colorOverrides` escape hatch for themes that want to
 * pin specific shadcn tokens to exact values (e.g. a pastel theme that
 * needs a softer `destructive` red than the derived default).
 */

/** A color layer: hex base + alpha (0–1). */
export interface ThemeLayer {
  alpha: number;
  hex: string;
}

export interface ThemePalette {
  /** Deepest canvas color (typically near-black). */
  background: ThemeLayer;
  /** Primary text + accent. Most UI chrome reads this. */
  midground: ThemeLayer;
  /** Top-layer highlight. In LENS_0 this is white @ alpha 0 — invisible by
   *  default but still drives `--color-ring`-style accents. */
  foreground: ThemeLayer;
  /** Warm vignette color for <Backdrop />, as an rgba() string. */
  warmGlow: string;
  /** Scalar multiplier (0–1.2) on the noise overlay. Lower for softer themes
   *  like Mono and Rosé, higher for grittier themes like Cyberpunk. */
  noiseOpacity: number;
}

export interface ThemeTypography {
  /** CSS font-family stack for sans-serif body copy. */
  fontSans: string;
  /** CSS font-family stack for monospace / code blocks. */
  fontMono: string;
  /** Optional display/heading font stack. Falls back to `fontSans`. */
  fontDisplay?: string;
  /** Optional external stylesheet URL (e.g. Google Fonts, Bunny Fonts,
   *  self-hosted .woff2 @font-face sheet). Injected as a <link> in <head>
   *  on theme switch. Same URL is never injected twice. */
  fontUrl?: string;
  /** Root font size (controls rem scale). Example: `"14px"`, `"16px"`. */
  baseSize: string;
  /** Default line-height. Example: `"1.5"`, `"1.65"`. */
  lineHeight: string;
  /** Default letter-spacing. Example: `"0"`, `"0.01em"`, `"-0.01em"`. */
  letterSpacing: string;
}

export type ThemeDensity = "compact" | "comfortable" | "spacious";

export interface ThemeLayout {
  /** Corner-radius token. Example: `"0"`, `"0.25rem"`, `"0.5rem"`,
   *  `"1rem"`. Maps to `--radius` and cascades into every component. */
  radius: string;
  /** Spacing multiplier. `compact` = 0.85, `comfortable` = 1.0 (default),
   *  `spacious` = 1.2. Applied via the `--spacing-mul` CSS var. */
  density: ThemeDensity;
}

/** Overall layout variant the shell renders. `standard` = default single-
 *  column page layout. `cockpit` = reserves a left sidebar rail for a
 *  plugin slot (intended for HUD-style themes with persistent status panels).
 *  `tiled` = relaxes the main content max-width so pages can use the full
 *  viewport width. Themes set this; plugins react via CSS vars /
 *  `[data-layout-variant="..."]` selectors. */
export type ThemeLayoutVariant = "standard" | "cockpit" | "tiled";

/** Named hero/background assets a theme can populate. Each value is
 *  emitted as a CSS var (`--theme-asset-<name>`). The default shell
 *  consumes `bg` in `<Backdrop />` when present; other slots are
 *  plugin-facing — a cockpit sidebar plugin reads `--theme-asset-hero`
 *  to render its hero render without coupling to the theme name. */
export interface ThemeAssets {
  /** Full-viewport background image URL, injected under the noise layer. */
  bg?: string;
  /** Hero render (Gundam, mascot, wallpaper) — for plugin sidebars/overlays. */
  hero?: string;
  /** Logo mark — header slot consumers use this. */
  logo?: string;
  /** Faction/brand crest — header-left decoration. */
  crest?: string;
  /** Secondary sidebar illustration. */
  sidebar?: string;
  /** Alternate header artwork. */
  header?: string;
  /** User-defined named assets. Keyed by [a-zA-Z0-9_-] only.
   *  Emitted as `--theme-asset-custom-<key>`. */
  custom?: Record<string, string>;
}

/** Component-style override buckets. Each bucket's entries become CSS
 *  vars (`--component-<bucket>-<kebab-property>`) that shell components
 *  (Card, Backdrop, App header/footer, etc.) read. Values are plain CSS
 *  strings — we don't parse them, so themes can use `clip-path`,
 *  `border-image`, `background`, `box-shadow`, and anything else CSS
 *  accepts. */
export interface ThemeComponentStyles {
  card?: Record<string, string>;
  header?: Record<string, string>;
  footer?: Record<string, string>;
  sidebar?: Record<string, string>;
  tab?: Record<string, string>;
  progress?: Record<string, string>;
  badge?: Record<string, string>;
  backdrop?: Record<string, string>;
  page?: Record<string, string>;
}

/** Data-series accent colors for chart + table visualisations (Analytics,
 *  Models, etc.). Themes provide hex strings; the provider emits them as
 *  `--series-input-token` / `--series-output-token` CSS vars consumed
 *  inline by pages that render input-vs-output token flows. Themes can
 *  omit either field to inherit the default token defined in
 *  `index.css` (Hermes-teal `#ffe6cb` for input, `#34d399` for output).
 *
 *  Inverted-lens themes (e.g. Nous Blue) must pre-invert these hex
 *  values so they read as their intended visual color after the FG
 *  difference layer flips them (`out = 255 − channel`). E.g. to make
 *  output paint as Nous-blue `#0053FD` on screen, set
 *  `outputTokenAccent: "#FFAC02"` — the difference math reverses it. */
export interface ThemeSeriesColors {
  /** Input-tokens series accent (Analytics chart bars + table values). */
  inputTokenAccent?: string;
  /** Output-tokens series accent. */
  outputTokenAccent?: string;
}

/** Optional hex overrides keyed by shadcn-compat token name (without the
 *  `--color-` prefix). Any key set here wins over the DS cascade. */
export interface ThemeColorOverrides {
  card?: string;
  cardForeground?: string;
  popover?: string;
  popoverForeground?: string;
  primary?: string;
  primaryForeground?: string;
  secondary?: string;
  secondaryForeground?: string;
  muted?: string;
  mutedForeground?: string;
  accent?: string;
  accentForeground?: string;
  destructive?: string;
  destructiveForeground?: string;
  success?: string;
  warning?: string;
  border?: string;
  input?: string;
  ring?: string;
}

export interface DashboardTheme {
  description: string;
  label: string;
  name: string;
  palette: ThemePalette;
  typography: ThemeTypography;
  layout: ThemeLayout;
  /** Overall shell layout. Defaults to `"standard"` when absent. */
  layoutVariant?: ThemeLayoutVariant;
  /** Named + custom asset URLs exposed as CSS vars on theme apply. */
  assets?: ThemeAssets;
  /** Raw CSS injected as a scoped `<style>` tag on theme apply, cleaned up
   *  on theme switch. Intended for selector-level chrome that's too
   *  expressive for componentStyles alone (e.g. `::before` pseudo-elements,
   *  complex animations, media queries). */
  customCSS?: string;
  /** Per-component CSS-var overrides. See `ThemeComponentStyles`. */
  componentStyles?: ThemeComponentStyles;
  colorOverrides?: ThemeColorOverrides;
  /** Data-series accent colors for Analytics/Models token charts.
   *  See `ThemeSeriesColors` for inversion-aware values. */
  seriesColors?: ThemeSeriesColors;
  /** Explicit 3-color swatch override for the theme picker. Use when the
   *  palette's raw hex values don't reflect what users see on screen —
   *  e.g. inverted "lens" themes whose foreground-difference layer flips
   *  the authored colors to their visual complements. Order matches the
   *  default swatch cells: [background, midground, warmGlow]. */
  swatchColors?: [string, string, string];
  /** Background color for the embedded terminal pane (xterm.js).
   *  Hex string. Defaults to `"#000000"` when absent. */
  terminalBackground?: string;
}

/**
 * Wire response shape for `GET /api/dashboard/themes`.
 *
 * The `themes` list is intentionally partial — built-in themes are fully
 * defined in `presets.ts`; user themes carry their full definition so the
 * client can apply them without a second round-trip.
 */
export interface ThemeListEntry {
  description: string;
  label: string;
  name: string;
  /** Full theme definition. Present for user-defined themes loaded from
   *  `~/.hermes/dashboard-themes/*.yaml`; undefined for built-ins (the
   *  client already has those in `BUILTIN_THEMES`). */
  definition?: DashboardTheme;
}

export interface ThemeListResponse {
  active: string;
  themes: ThemeListEntry[];
}
