/**
 * Theme system for the editor.
 *
 * Themes are CSS variable overrides scoped to the editor shell element.
 * A theme can be a preset name (string) or a config object with color
 * and syntax highlighting overrides.
 *
 * Usage:
 *   <Editor theme="kanagawa" />
 *   <Editor :theme="{ colors: { primary: '#3b82f6' } }" />
 */

// ── Types ──────────────────────────────────────────────────────────

export interface ThemeColors {
  primary?: string
  success?: string
  error?: string
  neutral?: string

  text?: {
    main?: string
    muted?: string
    highlight?: string
  }

  background?: {
    elevated?: string
  }

  border?: string
}

export interface ThemeSyntax {
  keyword?: string
  string?: string
  string2?: string
  comment?: string
  number?: string
  atom?: string
  bool?: string
  null?: string
  type?: string
  typeName?: string
  className?: string
  function?: string
  definition?: string
  variableName?: string
  propertyName?: string
  attributeName?: string
  operator?: string
  punctuation?: string
  tag?: string
  meta?: string
}

export interface EditorTheme {
  name?: string
  colors?: ThemeColors
  syntax?: ThemeSyntax
}

export type ThemeInput = string | EditorTheme

// ── Default theme (uses @nuxt/ui variables as-is) ──────────────────

const defaultTheme: EditorTheme = {
  name: "default",
}

// ── Built-in presets ───────────────────────────────────────────────

const kanagawa: EditorTheme = {
  name: "kanagawa",
  colors: {
    primary: "#7fb4ca",
    success: "#98bb6c",
    error: "#e46876",
    neutral: "#727169",
    text: {
      main: "#dcd7ba",
      muted: "#727169",
      highlight: "#e6c384",
    },
    background: {
      elevated: "#1f1f28",
    },
    border: "#363646",
  },
  syntax: {
    keyword: "#e6c384",
    string: "#98bb6c",
    string2: "#98bb6c",
    comment: "#727169",
    number: "#dca561",
    atom: "#e46876",
    bool: "#e46876",
    null: "#e46876",
    type: "#7e9cd8",
    typeName: "#7e9cd8",
    className: "#7e9cd8",
    function: "#7fb4ca",
    definition: "#7fb4ca",
    variableName: "#dcd7ba",
    propertyName: "#dcd7ba",
    attributeName: "#7fb4ca",
    operator: "#dcd7ba",
    punctuation: "#dcd7ba",
    tag: "#7fb4ca",
    meta: "#e6c384",
  },
}

export const themePresets: Record<string, EditorTheme | undefined> = {
  default: defaultTheme,
  kanagawa,
}

// ── Resolution ─────────────────────────────────────────────────────

export function resolveTheme(input: ThemeInput | undefined): EditorTheme {
  if (!input || input === "default") return defaultTheme

  if (typeof input === "string") {
    const preset = themePresets[input]
    if (preset) return preset
    console.warn(
      `[editor] unknown theme preset "${input}", falling back to default`,
    )
    return defaultTheme
  }

  return input
}

// ── CSS variable mapping ───────────────────────────────────────────

/**
 * Map a resolved theme to CSS variable overrides scoped to the editor
 * shell element. Variables using `--ui-*` prefixes cascade into all
 * child components (Block, InsertionZone, CodeBlockView) overriding
 * the page-level @nuxt/ui values. Syntax variables override the
 * `--code-*` values used by CM6 syntax highlighting.
 *
 * Because these are set inline on the editor shell, they do NOT leak
 * to sibling or ancestor elements outside the editor.
 */
export function themeToCSSVars(theme: EditorTheme): Record<string, string> {
  const vars: Record<string, string> = {}
  const c = theme.colors
  if (!c) return vars

  // Map to --ui-* variables (overrides @nuxt/ui at editor scope)
  if (c.primary) vars["--ui-primary"] = c.primary
  if (c.success) vars["--ui-success"] = c.success
  if (c.error) vars["--ui-error"] = c.error
  if (c.text?.main) vars["--ui-text-main"] = c.text.main
  if (c.text?.muted) vars["--ui-text-muted"] = c.text.muted
  if (c.text?.highlight) vars["--ui-text-highlight"] = c.text.highlight
  if (c.background?.elevated) vars["--ui-bg-elevated"] = c.background.elevated
  if (c.border) vars["--ui-border"] = c.border

  // Map to --code-* variables (overrides syntax highlighting at editor scope)
  const s = theme.syntax
  if (s) {
    if (s.keyword) vars["--code-keyword"] = s.keyword
    if (s.string) vars["--code-string"] = s.string
    if (s.string2) vars["--code-string2"] = s.string2
    if (s.comment) vars["--code-comment"] = s.comment
    if (s.number) vars["--code-number"] = s.number
    if (s.atom) vars["--code-atom"] = s.atom
    if (s.bool) vars["--code-bool"] = s.bool
    if (s.null) vars["--code-null"] = s.null
    if (s.type) vars["--code-type"] = s.type
    if (s.typeName) vars["--code-typeName"] = s.typeName
    if (s.className) vars["--code-className"] = s.className
    if (s.function) vars["--code-function"] = s.function
    if (s.definition) vars["--code-definition"] = s.definition
    if (s.variableName) vars["--code-variableName"] = s.variableName
    if (s.propertyName) vars["--code-propertyName"] = s.propertyName
    if (s.attributeName) vars["--code-attributeName"] = s.attributeName
    if (s.operator) vars["--code-operator"] = s.operator
    if (s.punctuation) vars["--code-punctuation"] = s.punctuation
    if (s.tag) vars["--code-tag"] = s.tag
    if (s.meta) vars["--code-meta"] = s.meta
  }

  return vars
}
