'use client'

import { useEffect, useState } from 'react'

/**
 * App theme preference. 'system' follows the OS (prefers-color-scheme) and is
 * the default; 'light' / 'dark' are explicit overrides. The resolved theme is
 * applied by toggling the `dark` class on <html> (Tailwind darkMode via
 * @custom-variant in globals.css).
 *
 * The same localStorage key is read by the inline FOUC guard in layout.tsx so
 * the correct class is set before React mounts — keep THEME_STORAGE_KEY in sync there.
 */
export type ThemePref = 'system' | 'light' | 'dark'

export const THEME_STORAGE_KEY = 'iamcavalli:theme'

function systemPrefersDark(): boolean {
  return (
    typeof window !== 'undefined' &&
    window.matchMedia('(prefers-color-scheme: dark)').matches
  )
}

export function readThemePref(): ThemePref {
  if (typeof window === 'undefined') return 'system'
  const v = window.localStorage.getItem(THEME_STORAGE_KEY)
  return v === 'light' || v === 'dark' ? v : 'system'
}

export function resolveTheme(pref: ThemePref): 'light' | 'dark' {
  return pref === 'system' ? (systemPrefersDark() ? 'dark' : 'light') : pref
}

export function applyTheme(pref: ThemePref): void {
  if (typeof document === 'undefined') return
  document.documentElement.classList.toggle('dark', resolveTheme(pref) === 'dark')
}

/**
 * Theme state hook. Initialises to 'system' on both server and first client
 * render (avoids hydration mismatch — the FOUC guard already set the <html>
 * class), then reconciles from localStorage after mount. Applies the resolved
 * theme on change and, while in 'system' mode, re-applies live when the OS
 * theme flips. Returns the raw preference, the resolved light/dark value, and a
 * setter that persists (clearing the key for 'system' so the OS stays
 * authoritative).
 */
export function useTheme() {
  const [pref, setPref] = useState<ThemePref>('system')

  useEffect(() => {
    setPref(readThemePref())
  }, [])

  useEffect(() => {
    applyTheme(pref)
    if (pref !== 'system') return
    const mq = window.matchMedia('(prefers-color-scheme: dark)')
    const onChange = () => applyTheme('system')
    mq.addEventListener('change', onChange)
    return () => mq.removeEventListener('change', onChange)
  }, [pref])

  function setTheme(next: ThemePref) {
    if (next === 'system') window.localStorage.removeItem(THEME_STORAGE_KEY)
    else window.localStorage.setItem(THEME_STORAGE_KEY, next)
    setPref(next)
  }

  return { pref, resolved: resolveTheme(pref), setTheme }
}
