import { marked } from 'marked'
import type { HLJSApi, LanguageFn } from 'highlight.js'
import hljsCore from 'highlight.js/lib/core'
import javascript from 'highlight.js/lib/languages/javascript'
import typescript from 'highlight.js/lib/languages/typescript'
import python from 'highlight.js/lib/languages/python'
import go from 'highlight.js/lib/languages/go'
import java from 'highlight.js/lib/languages/java'
import css from 'highlight.js/lib/languages/css'
import xml from 'highlight.js/lib/languages/xml'
import json from 'highlight.js/lib/languages/json'
import bash from 'highlight.js/lib/languages/bash'
import sql from 'highlight.js/lib/languages/sql'
import yaml from 'highlight.js/lib/languages/yaml'
import markdown from 'highlight.js/lib/languages/markdown'
import rust from 'highlight.js/lib/languages/rust'
import cpp from 'highlight.js/lib/languages/cpp'
import c from 'highlight.js/lib/languages/c'
import php from 'highlight.js/lib/languages/php'
import shell from 'highlight.js/lib/languages/shell'

const LANGUAGE_REGISTRY: Array<[string, LanguageFn]> = [
  ['javascript', javascript],
  ['typescript', typescript],
  ['python', python],
  ['go', go],
  ['java', java],
  ['css', css],
  ['xml', xml],
  ['html', xml],
  ['json', json],
  ['bash', bash],
  ['sh', bash],
  ['sql', sql],
  ['yaml', yaml],
  ['yml', yaml],
  ['markdown', markdown],
  ['md', markdown],
  ['rust', rust],
  ['cpp', cpp],
  ['c', c],
  ['php', php],
  ['shell', shell],
]

let hljsInstance: HLJSApi | null = null
let configured = false

function getHljs(): HLJSApi {
  if (!hljsInstance) {
    hljsInstance = hljsCore
    for (const [name, register] of LANGUAGE_REGISTRY) {
      hljsInstance.registerLanguage(name, register)
    }
  }
  return hljsInstance
}

function ensureMarked() {
  if (configured) return
  const hljs = getHljs()
  marked.setOptions({
    gfm: true,
    breaks: false,
  })
  const renderer = new marked.Renderer()
  renderer.code = ({ text, lang }: { text: string, lang?: string }) => {
    const language = (lang || '').split(/\s+/)[0]
    let highlighted = text
    if (language && hljs.getLanguage(language)) {
      try {
        highlighted = hljs.highlight(text, { language, ignoreIllegals: true }).value
      }
      catch {
        highlighted = hljs.highlightAuto(text).value
      }
    }
    else {
      highlighted = hljs.highlightAuto(text).value
    }
    return `<pre class="hljs"><code class="language-${language || 'text'}">${highlighted}</code></pre>\n`
  }
  renderer.heading = ({ text, depth }: { text: string, depth: number }) => {
    const slug = `heading-${String(text).toLowerCase().replace(/[^\w\u4e00-\u9fa5]+/g, '-')}`
    return `<h${depth} id="${slug}">${text}</h${depth}>\n`
  }
  renderer.image = ({ href, text }: { href: string, text: string }) => {
    return `<img src="${href}" alt="${text || ''}" style="max-width:100%;border-radius:8px;" />`
  }
  marked.use({ renderer })
  configured = true
}

export async function renderMarkdown(content: string): Promise<string> {
  if (!content) return ''
  ensureMarked()
  return marked.parse(content) as string
}

export function preloadMarkdownRenderer(): void {
  getHljs()
  ensureMarked()
}
