import { createContext, type PropsWithChildren, useContext, useEffect, useMemo, useState } from 'react'
import type { PaletteMode } from '@mui/material'
import type { ColorScheme, ThemeModePreference } from '@/shared/model/theme'

export type ThemeSettings = {
  mode: ThemeModePreference
  scheme: ColorScheme
}

export type ThemeController = ThemeSettings & {
  /** Итоговый режим, учитывая system. */
  resolvedMode: PaletteMode
  setMode: (mode: ThemeModePreference) => void
  toggleMode: () => void
  cycleMode: () => void
  setScheme: (scheme: ColorScheme) => void
}

const THEME_STORAGE_KEY = 'craftshop_theme'

function readStoredTheme(): ThemeSettings | null {
  try {
    const raw = localStorage.getItem(THEME_STORAGE_KEY)
    if (!raw) return null
    const parsed = JSON.parse(raw)
    const mode: unknown = parsed?.mode
    const scheme: unknown = parsed?.scheme
    const modeOk = mode === 'light' || mode === 'dark' || mode === 'system'
    const schemeOk = scheme === 'craft' || scheme === 'forest' || scheme === 'ocean' || scheme === 'berry'
    if (!modeOk || !schemeOk) return null
    return { mode, scheme }
  } catch {
    return null
  }
}

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

function resolveMode(pref: ThemeModePreference): PaletteMode {
  return pref === 'system' ? getSystemMode() : pref
}

const ThemeControllerContext = createContext<ThemeController | null>(null)

export function useThemeController(): ThemeController {
  const ctx = useContext(ThemeControllerContext)
  if (!ctx) throw new Error('useThemeController must be used within ThemeControllerProvider')
  return ctx
}

export function ThemeControllerProvider({ children }: PropsWithChildren) {
  const [settings, setSettings] = useState<ThemeSettings>(
    () => readStoredTheme() ?? { mode: 'system', scheme: 'craft' },
  )

  const [systemMode, setSystemMode] = useState<PaletteMode>(() => getSystemMode())

  useEffect(() => {
    const mql = window.matchMedia?.('(prefers-color-scheme: dark)')
    if (!mql) return

    const handler = () => setSystemMode(mql.matches ? 'dark' : 'light')

    // начальное значение
    handler()

    if (typeof mql.addEventListener === 'function') {
      mql.addEventListener('change', handler)
      return () => mql.removeEventListener('change', handler)
    }

    // Safari старых версий
    mql.addListener(handler)
    return () => mql.removeListener(handler)
  }, [])

  useEffect(() => {
    try {
      localStorage.setItem(THEME_STORAGE_KEY, JSON.stringify(settings))
    } catch {
      // ignore
    }
  }, [settings])

  const resolvedMode = settings.mode === 'system' ? systemMode : settings.mode

  const controller = useMemo<ThemeController>(
    () => ({
      mode: settings.mode,
      resolvedMode,
      scheme: settings.scheme,
      setMode: (mode) => setSettings((s) => ({ ...s, mode })),
      toggleMode: () =>
        setSettings((s) => ({
          ...s,
          mode: resolveMode(s.mode) === 'light' ? 'dark' : 'light',
        })),
      cycleMode: () =>
        setSettings((s) => ({
          ...s,
          mode: s.mode === 'system' ? 'light' : s.mode === 'light' ? 'dark' : 'system',
        })),
      setScheme: (scheme) => setSettings((s) => ({ ...s, scheme })),
    }),
    [resolvedMode, settings.mode, settings.scheme],
  )

  return <ThemeControllerContext.Provider value={controller}>{children}</ThemeControllerContext.Provider>
}
