import { marked } from 'marked'
import { markedHighlight } from 'marked-highlight'
import hljs from 'highlight.js'
import 'highlight.js/styles/github-dark.css'
import katex from 'katex'
import 'katex/dist/katex.min.css'
import DOMPurify from 'dompurify'

marked.use(markedHighlight({
  langPrefix: 'hljs language-',
  highlight(code, lang) {
    if (lang && hljs.getLanguage(lang)) {
      return hljs.highlight(code, { language: lang }).value
    }
    return hljs.highlightAuto(code).value
  },
}))
marked.setOptions({ breaks: true, gfm: true })

// LaTeX-Mathe via KaTeX. Eigene marked-Extensions (statt marked-katex-extension,
// die marked v18 hinterherhinkt). marked tokenisiert Code zuerst → $…$ in Code-
// Blöcken wird NICHT als Mathe erkannt. throwOnError:false zeigt defektes TeX rot.
function renderTex(tex, displayMode) {
  return katex.renderToString(tex, { displayMode, throwOnError: false, output: 'html' })
}

const blockMath = {
  name: 'blockMath',
  level: 'block',
  start(src) { const i = src.indexOf('$$'); return i < 0 ? undefined : i },
  tokenizer(src) {
    const m = /^\$\$([\s\S]+?)\$\$/.exec(src)
    if (m) return { type: 'blockMath', raw: m[0], text: m[1].trim() }
  },
  renderer(token) { return renderTex(token.text, true) },
}

const inlineMath = {
  name: 'inlineMath',
  level: 'inline',
  start(src) { const i = src.indexOf('$'); return i < 0 ? undefined : i },
  tokenizer(src) {
    // $…$: kein $$, kein Leerzeichen direkt hinter dem öffnenden $ und vor dem
    // schließenden $ (pandoc-Stil) → mindert Kollisionen mit Fließtext-Dollarzeichen.
    const m = /^\$(?![\s$])((?:\\\$|[^$])+?)\$/.exec(src)
    if (!m || /\s$/.test(m[1])) return
    return { type: 'inlineMath', raw: m[0], text: m[1].trim() }
  },
  renderer(token) { return renderTex(token.text, false) },
}

marked.use({ extensions: [blockMath, inlineMath] })

// Rohes HTML im Markdown (z. B. <p>, <img> ohne Backticks aus Agenten-Output)
// als Text anzeigen statt rendern — sonst verschluckt der Browser den Inhalt.
marked.use({
  renderer: {
    html(token) {
      const text = typeof token === 'string' ? token : token.text
      return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
    },
  },
})

export function renderMarkdown(text) {
  return DOMPurify.sanitize(marked.parse(text || ''))
}

// Inline-Variante (kein <p>-Wrapping) für kurze Texte wie Quiz-Optionen oder
// Lückentext-Satzteile — rendert $…$-Mathe und Markdown ohne Block-Umbruch.
export function renderMarkdownInline(text) {
  return DOMPurify.sanitize(marked.parseInline(text || ''))
}
