/* eslint-disable no-console */
import type { HighlighterCore, LanguageRegistration, ThemeInput } from '@shikijs/types'
import { createHighlighterCore } from '@shikijs/core'
import { createJavaScriptRegexEngine } from '@shikijs/engine-javascript'
import React, { createContext, useContext, useEffect, useMemo, useState } from 'react'

interface ShikiContextValue {
  highlighter: HighlighterCore | null
  isReady: boolean
  error: Error | null
}

interface ShikiProviderProps {
  children: React.ReactNode
  initialLanguages: LanguageRegistration[]
  initialThemes: ThemeInput[]
}

const ShikiContext = createContext<ShikiContextValue | null>(null)

export function ShikiProvider({ children, initialLanguages, initialThemes }: ShikiProviderProps) {
  const [highlighter, setHighlighter] = useState<HighlighterCore | null>(null)
  const [isReady, setIsReady] = useState(false)
  const [error, setError] = useState<Error | null>(null)

  useEffect(() => {
    const initHighlighter = async () => {
      try {
        const highlighterInstance = await createHighlighterCore({
          engine: createJavaScriptRegexEngine(),
        })

        setHighlighter(highlighterInstance)
        setIsReady(true)
        setError(null)
        // log the initial languages
        console.log('Initial languages:', initialLanguages)
        // log the initial themes
        console.log('Initial themes:', initialThemes)
        console.log('Initial theme 1:', initialThemes[0])
      }
      catch (err) {
        console.error('Highlighter initialization failed:', err)
        setError(err instanceof Error ? err : new Error('Initialization failed'))
        setIsReady(false)
      }
    }

    initHighlighter()
  }, [initialLanguages, initialThemes])

  const value = useMemo<ShikiContextValue>(
    () => ({
      highlighter,
      isReady,
      error,
    }),
    [highlighter, isReady, error],
  )

  return <ShikiContext.Provider value={value}>{children}</ShikiContext.Provider>
}

export function useShiki() {
  const context = useContext(ShikiContext)
  if (!context) {
    throw new Error('useShiki must be used within a ShikiProvider')
  }
  return context
}
