import { computed, ref, type Ref } from 'vue'

export type ThemePref = 'system' | 'light' | 'dark'
export type ResolvedTheme = 'light' | 'dark'

const STORAGE_KEY = 'theme-pref'

const themePref = ref<ThemePref>('system')
const resolvedTheme = ref<ResolvedTheme>('dark')
const forceDark = ref(false)
let initialized = false
let mediaQuery: MediaQueryList | null = null

function getSystemTheme(): ResolvedTheme {
  if (typeof window === 'undefined') return 'dark'
  return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
}

function readStoredPref(): ThemePref {
  try {
    const raw = localStorage.getItem(STORAGE_KEY)
    if (raw === 'light' || raw === 'dark' || raw === 'system') return raw
  } catch {
    /* ignore */
  }
  return 'system'
}

function resolve(pref: ThemePref): ResolvedTheme {
  if (forceDark.value) return 'dark'
  if (pref === 'system') return getSystemTheme()
  return pref
}

function applyToDocument(theme: ResolvedTheme) {
  const root = document.documentElement
  root.classList.toggle('dark', theme === 'dark')
  root.style.colorScheme = theme
  resolvedTheme.value = theme
}

function recompute() {
  applyToDocument(resolve(themePref.value))
}

function onSystemChange() {
  if (themePref.value === 'system' && !forceDark.value) {
    recompute()
  }
}

export function setForceDark(enabled: boolean) {
  forceDark.value = enabled
  recompute()
}

export function setThemePref(pref: ThemePref) {
  themePref.value = pref
  try {
    localStorage.setItem(STORAGE_KEY, pref)
  } catch {
    /* ignore */
  }
  recompute()
}

export function cycleTheme() {
  const order: ThemePref[] = ['system', 'light', 'dark']
  const idx = order.indexOf(themePref.value)
  setThemePref(order[(idx + 1) % order.length])
}

export function initTheme() {
  if (initialized) {
    recompute()
    return
  }
  initialized = true
  themePref.value = readStoredPref()
  mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
  mediaQuery.addEventListener('change', onSystemChange)
  recompute()
}

export function useTheme() {
  if (typeof window !== 'undefined' && !initialized) {
    initTheme()
  }

  const themeIcon = computed(() => {
    if (themePref.value === 'system') return 'monitor'
    if (themePref.value === 'light') return 'sun'
    return 'moon'
  })

  const themeLabel = computed(() => {
    if (themePref.value === 'system') return '跟随系统'
    if (themePref.value === 'light') return '亮色'
    return '暗色'
  })

  return {
    themePref: themePref as Ref<ThemePref>,
    resolvedTheme: resolvedTheme as Ref<ResolvedTheme>,
    themeIcon,
    themeLabel,
    setThemePref,
    cycleTheme,
    setForceDark,
    initTheme,
  }
}
