import { useEffect, useRef } from 'react'
import { renderThemeStudio, type ThemeStudioOptions } from '../components/theme/theme-studio'
import {
  THEME_LS_KEY,
  bootstrapTheme,
  getTheme,
  setThemePartial,
  type Theme,
} from '../services/theme-engine'

export type ThemeStudioSeedStrategy = 'if-empty' | 'always' | 'never'

export interface ThemeStudioProps extends ThemeStudioOptions {
  className?: string
  initialTheme?: Partial<Theme>
  onThemeChange?: (theme: Theme) => void
  seedStrategy?: ThemeStudioSeedStrategy
}

function hasPersistedTheme(): boolean {
  try {
    return typeof localStorage !== 'undefined' && localStorage.getItem(THEME_LS_KEY) !== null
  } catch {
    return false
  }
}

function shouldSeedTheme(
  initialTheme: Partial<Theme> | undefined,
  strategy: ThemeStudioSeedStrategy
): initialTheme is Partial<Theme> {
  if (!initialTheme || strategy === 'never') return false
  if (strategy === 'always') return true
  return !hasPersistedTheme()
}

function readThemeEvent(event: Event): Theme {
  if (event instanceof CustomEvent && event.detail) {
    return event.detail as Theme
  }
  return getTheme()
}

export function ThemeStudio({
  className,
  initialTheme,
  onThemeChange,
  seedStrategy = 'if-empty',
  showTabs,
  showHeader,
  showBrandSection,
}: ThemeStudioProps) {
  const containerRef = useRef<HTMLDivElement>(null)
  const onThemeChangeRef = useRef(onThemeChange)
  const seededRef = useRef(false)

  useEffect(() => {
    onThemeChangeRef.current = onThemeChange
  }, [onThemeChange])

  useEffect(() => {
    if (typeof document === 'undefined') return

    const handleThemeChange = (event: Event) => {
      onThemeChangeRef.current?.(readThemeEvent(event))
    }

    document.addEventListener('cm:theme-change', handleThemeChange)

    if (!seededRef.current) {
      seededRef.current = true
      if (shouldSeedTheme(initialTheme, seedStrategy)) {
        setThemePartial(initialTheme)
      }
    }

    bootstrapTheme()
    handleThemeChange(new CustomEvent('cm:theme-change', { detail: getTheme() }))

    return () => {
      document.removeEventListener('cm:theme-change', handleThemeChange)
    }
  }, [initialTheme, seedStrategy])

  useEffect(() => {
    const container = containerRef.current
    if (!container) return

    const options: ThemeStudioOptions = {}
    if (showTabs !== undefined) options.showTabs = showTabs
    if (showHeader !== undefined) options.showHeader = showHeader
    if (showBrandSection !== undefined) options.showBrandSection = showBrandSection

    renderThemeStudio(container, options)
    return () => {
      container.replaceChildren()
    }
  }, [showTabs, showHeader, showBrandSection])

  return (
    <div
      ref={containerRef}
      data-slot="theme-studio"
      className={['cmm-theme-studio-react', className].filter(Boolean).join(' ')}
    />
  )
}

ThemeStudio.displayName = 'ThemeStudio'

export type { Theme }
