import type { Root, Element } from 'hast'
import type { Plugin } from 'unified'
import { visit } from 'unist-util-visit'
import { fromHtmlIsomorphic } from 'hast-util-from-html-isomorphic'
import { renderMermaidToSvg } from '@/lib/mermaid-render'

/**
 * A rehype plugin that processes <div> elements with a data-mermaid attribute and renders the Mermaid chart to SVG.
 * It replaces the <div> with the rendered SVG or displays an error message if rendering fails.
 */
export const rehypeMermaidSsg: Plugin<[], Root> = () => async (tree: Root) => {
  const targets: { node: Element; parent: Element | Root; index: number }[] = []

  visit(tree, 'element', (node: Element, index, parent) => {
    if (
      node.tagName === 'div' &&
      node.properties?.['data-mermaid'] &&
      parent &&
      typeof index === 'number'
    ) {
      targets.push({ node, parent: parent as Element | Root, index })
    }
  })

  await Promise.all(
    targets.map(async ({ node, parent, index }) => {
      const chart = String(node.properties!['data-mermaid'])
      try {
        const svg = await renderMermaidToSvg(chart)
        const svgTree = fromHtmlIsomorphic(svg, { fragment: true })
        const svgNode = svgTree.children.find((c) => c.type === 'element') as Element | undefined
        svgNode?.properties.className?.push('max-w-160', 'mx-auto', 'my-4')
        if (svgNode?.properties.style) svgNode.properties.style = ''
        if (svgNode) {
          ;(parent.children as Element[])[index] = svgNode
        }
      } catch (err) {
        node.tagName = 'pre'
        node.properties = { className: ['text-red-500', 'text-sm'] }
        node.children = [{ type: 'text', value: `Mermaid render error: ${(err as Error).message}` }]
      }
    }),
  )
}
