import type { UiTheme } from './ui-theme'
import type { ThemeId, ThemeRegistryEntry } from '#cli/core/theme'
import {
  DARK_MESSAGE_COLORS,
  LIGHT_MESSAGE_COLORS,
  getRegisteredThemeIds,
  getThemeEntry,
  normalizeThemeId,
  registerThemeMessageColors,
} from '#cli/core/theme'
import { MONOKAI_UI_THEME } from './monokai'
import { MONOKAI_LIGHT_UI_THEME } from './monokai-light'
import {
  CLAUDE_THEME,
  CODEX_THEME,
  CURSOR_THEME,
  DIM_DARK_THEME,
  DIM_LIGHT_THEME,
  FLEXOKI_THEME,
  GITHUB_THEME,
  OPENCODE_THEME,
  VERCEL_THEME,
  XIGUASAY_THEME,
} from './community-themes'

/**
 * Full theme preset: UI tokens + palette (for components) combined with
 * message-type colors (for chat rendering). One object = one theme.
 */
export type FullThemePreset = Readonly<{
  /** The UI theme (palette + semantic tokens by color level). */
  ui: UiTheme
  /** Reference to the agent-layer registry entry (label, colorMode, messageColors). */
  entry: ThemeRegistryEntry
}>

// ---------------------------------------------------------------------------
// UI-side registry: maps ThemeId → UiTheme
// ---------------------------------------------------------------------------

const uiThemeRegistry = new Map<ThemeId, UiTheme>()

/** Register a complete theme (UI tokens + message colors). */
export function registerFullTheme(
  id: ThemeId,
  preset: FullThemePreset,
): void {
  uiThemeRegistry.set(id, preset.ui)
  registerThemeMessageColors(id, preset.entry)
}

/** Get the `UiTheme` for a given theme ID, falling back to monokai-dark. */
export function getUiTheme(id: ThemeId): UiTheme {
  const resolved = normalizeThemeId(id)
  return uiThemeRegistry.get(resolved) ?? MONOKAI_UI_THEME
}

/** Get the full preset for a given theme ID. */
export function getFullThemePreset(id: ThemeId): FullThemePreset | undefined {
  const resolved = normalizeThemeId(id)
  const ui = uiThemeRegistry.get(resolved)
  const entry = getThemeEntry(resolved)
  if (!ui || !entry) return undefined
  return { ui, entry }
}

/** Return all registered theme IDs (from the agent-layer registry). */
export { getRegisteredThemeIds }

/** Resolve a raw value to a UiTheme. Backward-compat helper. */
export function resolveUiThemeForMode(mode: unknown): UiTheme {
  const id = normalizeThemeId(mode)
  return getUiTheme(id)
}

// ---------------------------------------------------------------------------
// Register built-in themes
// ---------------------------------------------------------------------------

// The agent-layer registry already has monokai-dark/monokai-light message
// colors registered (see packages/agent/src/core/theme.ts). Here we add the
// UI side so `getUiTheme` / `getFullThemePreset` work.

uiThemeRegistry.set('monokai-dark', MONOKAI_UI_THEME)
uiThemeRegistry.set('monokai-light', MONOKAI_LIGHT_UI_THEME)

// ---------------------------------------------------------------------------
// Community / brand themes
// ---------------------------------------------------------------------------

const communityThemes: Array<{
  id: ThemeId
  label: string
  colorMode: 'dark' | 'light'
  ui: UiTheme
}> = [
  { id: 'dim-dark', label: 'Dim Dark', colorMode: 'dark', ui: DIM_DARK_THEME },
  { id: 'dim-light', label: 'Dim Light', colorMode: 'light', ui: DIM_LIGHT_THEME },
  { id: 'github', label: 'GitHub', colorMode: 'dark', ui: GITHUB_THEME },
  { id: 'vercel', label: 'Vercel', colorMode: 'dark', ui: VERCEL_THEME },
  { id: 'cursor', label: 'Cursor', colorMode: 'dark', ui: CURSOR_THEME },
  { id: 'opencode', label: 'OpenCode', colorMode: 'dark', ui: OPENCODE_THEME },
  { id: 'flexoki', label: 'Flexoki', colorMode: 'dark', ui: FLEXOKI_THEME },
  { id: 'claude', label: 'Claude', colorMode: 'dark', ui: CLAUDE_THEME },
  { id: 'codex', label: 'Codex', colorMode: 'dark', ui: CODEX_THEME },
  { id: 'xiguasay', label: 'XiguaSay', colorMode: 'dark', ui: XIGUASAY_THEME },
]

for (const t of communityThemes) {
  const msgColors = t.colorMode === 'dark' ? DARK_MESSAGE_COLORS : LIGHT_MESSAGE_COLORS
  registerFullTheme(t.id, {
    ui: t.ui,
    entry: { label: t.label, colorMode: t.colorMode, messageColors: msgColors },
  })
}
