'use client'

import { useEffect, useState } from 'react'

import { IS_PROD } from '../constants'

const defaultDark: { [name: string]: string } = {
  '--brand-accent': '160deg 100% 50%',
  '--brand-default': '159.9deg 100% 38.6%',
  '--brand-600': '136deg 59.5% 70%',
  '--brand-500': '160.4deg 100% 19.2%',
  '--brand-400': '160.4deg 100% 9.6%',
  '--brand-300': '158.4deg 100% 4.9%',
  '--brand-200': '162deg 100% 2%',
  '--border-stronger': '200deg 16.1% 22%',
  '--border-strong': '200deg 16.5% 17.8%',
  '--border-alternative': '200deg 16.4% 13.1%',
  '--border-control': '200deg 10% 14%',
  '--border-overlay': '200deg 20% 9%',
  '--border-secondary': '200deg 21.6% 10%',
  '--border-muted': '200deg 14.9% 9.2%',
  '--border-default': '200deg 10% 11%',
  '--background-muted': '200deg 9.1% 10.8%',
  '--background-overlay-hover': '200deg 20% 11%',
  '--background-overlay-default': '200deg 14.3% 6.9%',
  '--background-surface-300': '200deg 20% 10%',
  '--background-surface-200': '200deg 20% 7%',
  '--background-surface-100': '200deg 20% 6%',
  '--background-control': '200deg 9% 11%',
  '--background-selection': '200deg 9.8% 10%',
  '--background-alternative': '200deg 20% 2.9%',
  '--background-default': '200deg 20% 4%',
  '--foreground-muted': '200deg 10% 35%',
  '--foreground-lighter': '200deg 8% 55%',
  '--foreground-light': '200deg 5% 69%',
  '--foreground-default': '200deg 0% 93%',
}

/**
 * Shows a GUI to test color themes in dev and preview env.
 *
 * To access sandbox mode:
 * - switch theme to dark mode
 * - append "#theme-sandbox" to the url
 * - select "Apply Theme" to apply preset (localStorage will keep track of changes so you don't lose new values)
 * - select "Reset localStorage" and refresh page to restart
 */
export const useThemeSandbox = (): any => {
  const isWindowUndefined = typeof window === 'undefined'
  if (isWindowUndefined || IS_PROD) return null
  const hash = window.location.hash
  const defaultConfig = defaultDark // use dark default tokens
  // const defaultConfig = defaultLight // use light default tokens
  const localPreset = localStorage.getItem('theme-sandbox')
  const isSandbox = hash.includes('#theme-sandbox') || localPreset !== null
  const [themeConfig, setThemeConfig] = useState(
    localPreset ? JSON.parse(localPreset) : defaultConfig
  )
  const styles = document.querySelector(':root') as any

  const handleSetThemeConfig = (name: string, value: any) => {
    updateCSSVariables()
    setThemeConfig((prevConfig: any) => ({ ...prevConfig, [name]: value }))
  }

  const updateCSSVariables = () => {
    Object.entries(themeConfig).map(([key, value]) => styles.style.setProperty(key, value))
    localStorage.setItem('theme-sandbox', JSON.stringify(themeConfig))
  }

  const init = async () => {
    if (!isSandbox) return
    const dat = await import('dat.gui')
    const gui = new dat.GUI()

    gui.width = 500

    Object.entries(defaultConfig).map(([key, _value]) => {
      if (!themeConfig[key]) return localStorage.removeItem('theme-sandbox')
      const folderName = key.split('-')[2]
      const folder = gui.__folders[folderName] ?? gui.addFolder(folderName)

      return folder
        .add(themeConfig, key)
        .name(key)
        .onChange((newValue) => {
          handleSetThemeConfig(key, newValue)
        })
    })

    var obj = {
      'Apply Theme': function () {
        updateCSSVariables()
      },
      'Exit Sandbox': function () {
        gui.destroy()
      },
      'Reset localStorage': function () {
        localStorage.removeItem('theme-sandbox')
        setThemeConfig(defaultConfig)
      },
    }

    gui.add(obj, 'Apply Theme')
    gui.add(obj, 'Reset localStorage')
    gui.add(obj, 'Exit Sandbox')
    gui.load
  }

  useEffect(() => {
    init()
  }, [])

  return { themeConfig, handleSetThemeConfig, isSandbox }
}

export default useThemeSandbox
