"use client"

import type { JSX } from "react"

import { useEffect } from "react"

import { useAppDispatch } from "@shared/hooks/useAppDispatch"
import { useAppSelector } from "@shared/hooks/useAppSelector"
import { setThemePreference } from "@shared/store/appState"

import type { ThemePreference } from "@shared/store/appState/types"

const STORAGE_KEY = "theme"

const resolveTheme = (preference: ThemePreference): "light" | "dark" => {
	if (preference === "system") {
		if (typeof window === "undefined") return "light"
		return window.matchMedia("(prefers-color-scheme: dark)").matches
			? "dark"
			: "light"
	}
	return preference
}

const applyTheme = (preference: ThemePreference): void => {
	const resolved = resolveTheme(preference)
	document.documentElement.setAttribute("data-theme", resolved)
	document.documentElement.classList.remove("light", "dark")
	document.documentElement.classList.add(resolved)
}

export const useResolvedTheme = (): "light" | "dark" => {
	const themePreference = useAppSelector(
		(state) => state.appState.themePreference,
	)
	return resolveTheme(themePreference)
}

export const ThemeSync = (): JSX.Element | null => {
	const dispatch = useAppDispatch()
	const themePreference = useAppSelector(
		(state) => state.appState.themePreference,
	)

	// On mount: read localStorage and sync to Redux
	useEffect(() => {
		const stored = localStorage.getItem(STORAGE_KEY) as ThemePreference | null
		if (stored && (stored === "light" || stored === "dark" || stored === "system")) {
			dispatch(setThemePreference(stored))
		}
	}, [dispatch])

	// On preference change: persist + apply
	useEffect(() => {
		localStorage.setItem(STORAGE_KEY, themePreference)
		applyTheme(themePreference)
	}, [themePreference])

	// When "system": listen to OS theme changes
	useEffect(() => {
		if (themePreference !== "system") return

		const mq = window.matchMedia("(prefers-color-scheme: dark)")
		const handler = (): void => applyTheme("system")

		mq.addEventListener("change", handler)
		return () => mq.removeEventListener("change", handler)
	}, [themePreference])

	return null
}
