/* eslint-disable no-console */
import type { ThemedToken, ThemeRegistrationAny } from '@shikijs/types'
import React, { memo, useCallback, useEffect, useState } from 'react'
import { ScrollView, StyleSheet, Text, View } from 'react-native'
import { useShiki } from './SyntaxContext'

const DEBUG = true
function _log(...args: any[]) {
  if (DEBUG)
    console.log('[SyntaxHighlighter]', ...args)
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  line: {
    flexDirection: 'row',
    flexWrap: 'wrap',
  },
})

interface SyntaxHighlighterProps {
  code: string
  language: string
  theme?: string | ThemeRegistrationAny
  fontSize?: number
}

export const SyntaxHighlighter = memo(({ code, language, theme, fontSize = 14 }: SyntaxHighlighterProps) => {
  const { highlighter, isReady } = useShiki()
  const [tokens, setTokens] = useState<ThemedToken[][]>([])
  const [error, setError] = useState<string | null>(null)

  const highlight = useCallback(async () => {
    if (!highlighter || !isReady) {
      _log('Highlighter not ready:', { highlighter: !!highlighter, isReady })
      return
    }

    try {
      const loadedLangs = highlighter.getLoadedLanguages()
      _log('Available languages:', loadedLangs)

      const normalizedLang = language?.toLowerCase() || 'text'
      _log('Requested language:', normalizedLang)

      const langToUse = loadedLangs.includes(normalizedLang) ? normalizedLang : 'text'
      _log('Using language:', langToUse)

      // Validate theme is loaded
      const loadedThemes = highlighter.getLoadedThemes()
      if (typeof theme === 'string' && !loadedThemes.includes(theme)) {
        throw new Error(`Theme ${theme} not loaded. Available themes: ${loadedThemes.join(', ')}`)
      }

      // Get complete theme details
      const currentTheme = highlighter.getTheme(theme || 'default')
      _log('Theme details:', {
        name: currentTheme.name,
        type: currentTheme.type,
        tokenColors: currentTheme.tokenColors?.length,
        settings: currentTheme.settings?.length,
        firstTokenColor: currentTheme.tokenColors?.[0],
      })

      // Use codeToTokens with explanation to debug token mapping
      const results = highlighter.codeToTokens(code.trim(), {
        lang: langToUse,
        theme: theme || 'default',
        includeExplanation: true,
      })

      // In SyntaxHighlighter.tsx
      _log('Tokenization results:', {
        lineCount: results.tokens.length,
        totalTokens: results.tokens.flat().length,
        firstLine: results.tokens[0]?.map(t => ({
          content: t.content,
          color: t.color,
          fontStyle: t.fontStyle,
          scopes: t.explanation?.[0]?.scopes.map(s => ({
            scope: s.scopeName,
            matches: s.themeMatches?.map(m => ({
              scope: m.scope,
              settings: m.settings,
            })),
          })),
        })),
        uniqueColors: [...new Set(results.tokens.flat().map(t => t.color))],
      })

      setTokens(results.tokens)
      setError(null)
    }
    catch (err) {
      console.error('Highlighting error:', err)
      _log('Highlighting failed:', {
        error: err instanceof Error ? err.message : 'Unknown error',
        code: `${code.substring(0, 100)}...`,
      })
      setError(err instanceof Error ? err.message : 'Failed to highlight code')
    }
  }, [code, language, theme, highlighter, isReady])

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

  useEffect(() => {
    if (tokens.length > 0) {
      _log('Token analysis:', {
        lineCount: tokens.length,
        sample: tokens[0]?.slice(0, 2),
        colors: [...new Set(tokens.flat().map(t => t.color))],
      })
    }
  }, [tokens])

  if (!isReady) {
    return (
      <View style={styles.container}>
        <Text style={{ fontSize }}>{code}</Text>
      </View>
    )
  }

  if (error) {
    return (
      <View style={styles.container}>
        <Text style={{ color: 'red' }}>{error}</Text>
        <Text style={{ fontSize }}>{code}</Text>
      </View>
    )
  }

  return (
    <ScrollView horizontal style={styles.container}>
      <View>
        {tokens.map((line, i) => (
          <View key={i} style={styles.line}>
            {line.map((token, j) => (
              <Text
                key={`${i}-${j}`}
                style={{
                  color: token.color,
                  fontSize,
                  ...(token.fontStyle && token.fontStyle & 1 && { fontStyle: 'italic' }),
                  ...(token.fontStyle && token.fontStyle & 2 && { fontWeight: 'bold' }),
                  ...(token.bgColor && { backgroundColor: token.bgColor }),
                }}
              >
                {token.content}
              </Text>
            ))}
          </View>
        ))}
      </View>
    </ScrollView>
  )
})
