import type { ThemePreset } from './themes'

/** 可在系统配置中取色盘调整的品牌色变量 */
export const THEME_COLOR_FIELDS = [
  { key: '--mg-primary', label: '主色（背景基色）', hint: '全页背景、左侧导航、卡片底色、按钮' },
  { key: '--mg-primary-hover', label: '悬停/辉光', hint: '背景光晕、菜单高亮、悬停态' },
  { key: '--mg-accent', label: '强调/高光', hint: '点缀、边框高光、Logo 光晕' }
] as const

export type ThemeColorKey = (typeof THEME_COLOR_FIELDS)[number]['key']

export type ThemeColorOverrides = Partial<Record<ThemeColorKey, string>>

export type ThemeOverridesMap = Record<string, ThemeColorOverrides>

function parseHex(hex: string): [number, number, number] | null {
  const h = hex.trim().replace(/^#/, '')
  if (!/^[0-9a-f]{6}$/i.test(h)) return null
  return [parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16)]
}

export function hexToRgbString(hex: string): string {
  const c = parseHex(hex)
  return c ? `${c[0]}, ${c[1]}, ${c[2]}` : '0, 0, 0'
}

function mixHex(a: string, b: string, t: number): string {
  const ca = parseHex(a)
  const cb = parseHex(b)
  if (!ca || !cb) return a
  const ch = (i: number) => Math.round(ca[i] + (cb[i] - ca[i]) * t)
  const to = (n: number) => n.toString(16).padStart(2, '0')
  return `#${to(ch(0))}${to(ch(1))}${to(ch(2))}`
}

function lighten(hex: string, amount: number): string {
  return mixHex(hex, '#ffffff', amount)
}

function darken(hex: string, amount: number): string {
  return mixHex(hex, '#000000', amount)
}

/** 根据三项取色结果推导相关 CSS 变量与预览色 */
export function deriveThemeVars(
  base: ThemePreset,
  overrides: ThemeColorOverrides
): Record<string, string> {
  const vars = { ...base.vars }
  const primary = overrides['--mg-primary'] ?? vars['--mg-primary']
  const hover = overrides['--mg-primary-hover'] ?? vars['--mg-primary-hover']
  const accent = overrides['--mg-accent'] ?? vars['--mg-accent']

  if (overrides['--mg-primary']) {
    const bgDeep = darken(primary, 0.72)
    const bgMid = darken(primary, 0.48)
    const bgShallow = darken(primary, 0.58)
    const asideMain = darken(primary, 0.54)
    const asideDeep = darken(primary, 0.7)
    const cardBase = darken(primary, 0.38)
    const cardHi = darken(primary, 0.28)
    const cardDark = darken(primary, 0.62)

    vars['--mg-primary'] = primary
    vars['--mg-primary-rgb'] = hexToRgbString(primary)
    vars['--mg-primary-active'] = darken(primary, 0.35)
    vars['--mg-primary-dark-2'] = darken(primary, 0.35)
    vars['--mg-primary-light-3'] = lighten(primary, 0.22)
    vars['--mg-primary-light-5'] = lighten(primary, 0.35)
    vars['--mg-primary-light-7'] = mixHex(primary, '#888888', 0.45)
    vars['--mg-primary-light-8'] = mixHex(primary, '#666666', 0.55)
    vars['--mg-primary-light-9'] = mixHex(primary, '#444444', 0.65)

    vars['--mg-bg-app-1'] = bgShallow
    vars['--mg-bg-app-2'] = bgMid
    vars['--mg-bg-app-3'] = bgDeep
    vars['--mg-bg-app-deep-rgb'] = hexToRgbString(bgDeep)
    vars['--mg-bg-aside-1'] = asideMain
    vars['--mg-bg-aside-2'] = asideDeep
    vars['--mg-bg-aside-rgb'] = hexToRgbString(asideMain)
    vars['--mg-bg-card-rgb'] = hexToRgbString(cardBase)
    vars['--mg-bg-card-hi-rgb'] = hexToRgbString(cardHi)
    vars['--mg-bg-card-darker-rgb'] = hexToRgbString(cardDark)
    vars['--mg-shadow-rgb'] = hexToRgbString(darken(primary, 0.78))
  }

  if (overrides['--mg-primary-hover']) {
    vars['--mg-primary-hover'] = hover
    vars['--mg-primary-hover-rgb'] = hexToRgbString(hover)
  }

  if (overrides['--mg-accent']) {
    vars['--mg-accent'] = accent
    vars['--mg-accent-rgb'] = hexToRgbString(accent)
  }

  return vars
}

export function mergeThemePreset(
  preset: ThemePreset,
  overrides: ThemeColorOverrides | undefined
): ThemePreset {
  if (!overrides || Object.keys(overrides).length === 0) return preset
  const vars = deriveThemeVars(preset, overrides)
  return {
    ...preset,
    preview: overrides['--mg-primary'] ?? preset.preview,
    previewAccent: overrides['--mg-accent'] ?? preset.previewAccent,
    vars
  }
}

export function getOverrideOrDefault(
  preset: ThemePreset,
  overrides: ThemeColorOverrides | undefined,
  key: ThemeColorKey
): string {
  return overrides?.[key] ?? preset.vars[key]
}
