/**
 * Syntax highlighting for the code editor: Prism + prism-react-renderer + Nunjucks.
 * Nunjucks ({{ }}, {% %}, {# #}) is always applied so the editor supports templating everywhere.
 * Ensure prismSetup.ts is imported once in main.tsx, and prism theme: import 'prismjs/themes/prism.css'
 */
import React from 'react'
import Prism from 'prismjs'
import type { Grammar } from 'prismjs'
import { tokenizeWithNunjucks } from '@/lib/nunjucksTokenizer'

export type HighlightLanguage = 'javascript' | 'markdown' | 'plantuml'

const prismLang: Record<HighlightLanguage, string> = {
  javascript: 'javascript',
  markdown: 'markdown',
  plantuml: 'plantuml',
}

function getGrammar(language: HighlightLanguage): Grammar {
  const lang = prismLang[language]
  const g = (Prism.languages as Record<string, Grammar>)[lang]
  return g ?? {}
}

/**
 * Returns highlighted code as React nodes with Nunjucks support.
 * Used by the shared CodeEditor so all usages get the same features (base language + Nunjucks).
 */
export function highlight(
  code: string,
  language: HighlightLanguage
): React.ReactNode {
  const grammar = getGrammar(language)
  const lines = tokenizeWithNunjucks(code, grammar)
  return (
    <>
      {lines.map((lineTokens, i) => (
        <div key={i} className="token-line">
          {lineTokens.length > 0 ? (
            lineTokens.map((token, j) => (
              <span
                key={j}
                className={`token ${token.types.join(' ')}`}
              >
                {token.content}
              </span>
            ))
          ) : (
            <span className="token">&#8203;</span>
          )}
        </div>
      ))}
    </>
  )
}
