'use client'

import { useEffect, useId, useRef, useState } from 'react'

type Props = {
  source: string
}

let mermaidPromise: Promise<typeof import('mermaid').default> | null = null

function loadMermaid() {
  if (!mermaidPromise) {
    mermaidPromise = import('mermaid').then((mod) => {
      const mermaid = mod.default
      mermaid.initialize({
        startOnLoad: false,
        theme: 'default',
        securityLevel: 'strict',
        fontFamily: 'inherit',
      })
      return mermaid
    })
  }
  return mermaidPromise
}

export function MermaidBlock({ source }: Props) {
  const id = useId().replace(/[^a-zA-Z0-9]/g, '')
  const containerRef = useRef<HTMLDivElement | null>(null)
  const [error, setError] = useState<string | null>(null)

  useEffect(() => {
    let cancelled = false
    loadMermaid()
      .then(async (mermaid) => {
        if (cancelled) return
        try {
          const { svg } = await mermaid.render(`mermaid-${id}`, source)
          if (cancelled) return
          if (containerRef.current) containerRef.current.innerHTML = svg
          setError(null)
        } catch (err) {
          if (cancelled) return
          setError(err instanceof Error ? err.message : String(err))
        }
      })
      .catch((err) => {
        if (cancelled) return
        setError(err instanceof Error ? err.message : String(err))
      })
    return () => {
      cancelled = true
    }
  }, [id, source])

  if (error) {
    return (
      <pre className="overflow-x-auto rounded-md bg-muted p-3 text-xs text-destructive">
        <code>
          {`Mermaid render failed: ${error}\n\n${source}`}
        </code>
      </pre>
    )
  }

  return (
    <div
      ref={containerRef}
      className="my-4 flex justify-center overflow-x-auto rounded-md bg-muted p-4 [&_svg]:max-w-full"
      aria-label="Diagram"
    />
  )
}
