/// <reference types="@types/w3c-css-typed-object-model-level-1" />
import { kebabCase } from "lodash"
import type primer from "@primer/primitives/dist/json/colors/dark.json"
import { memo } from "react"
import { Helmet } from "react-helmet"
import type { tokenSource } from "~/shared/theme/tokens"

export const vars: {
  [key in keyof typeof tokenSource]: string
} = new Proxy({} as any, {
  get: (_, target: string) => `var(--${kebabCase(target)})`,
})

export const LIGHT_MODE = "body.light &"
export const DARK_MODE = "body.dark &"

export type Primer = typeof primer

function getProxy(prefix: string): any {
  return new Proxy({} as any, {
    get: (_, target) => {
      if (typeof target === "symbol") {
        return
      }
      if (target === "toString") {
        return () => `var(--color-${kebabCase(prefix)})`
      }
      return getProxy(prefix + "-" + target)
    },
  })
}

export const token: Primer = getProxy("")

const themes = [
  "dark",
  "dark-default",
  // "dark_colorblind",
  // "dark_dimmed",
  // "dark_high_contrast",
  // "dark_tritanopia",
  "light",
  "light-default",
  // "light_colorblind",
  // "light_high_contrast",
  // "light_tritanopia",
]

export const PrimerCSS = memo(() => (
  <Helmet>
    {themes.map(theme => (
      <link rel="stylesheet" key={theme} href={`/vendor/primer/github-${theme}.css`} />
    ))}
  </Helmet>
))

let rules: [CSSStyleRule, CSSStyleRule]
const idMap = new Map<string, number>()

export function color(light: string, dark: string) {
  if (rules == null) {
    const style = document.createElement("style")
    style.innerHTML = "body.light{}body.dark{}"
    document.head.appendChild(style)
    rules = style.sheet!.cssRules as any
  }

  const key = `${light}-${dark}`
  if (idMap.has(key)) {
    return `var(--c${idMap.get(key)})`
  }

  idMap.set(key, idMap.size + 1)
  const id = "--c" + idMap.get(key)!
  rules[0].style.setProperty(id, light)
  rules[1].style.setProperty(id, dark)
  return `var(${id})`
}
