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

import { cn } from './utils'
import { MermaidDiagram as MermaidDiagramVanilla } from '../../visualization/mermaid-diagram'
import type { MermaidTheme } from '../../visualization/mermaid-diagram/types'

export type { MermaidTheme, MermaidDiagramType } from '../../visualization/mermaid-diagram/types'

export interface MermaidDiagramProps {
  content: string
  theme?: MermaidTheme
  onRenderStart?: () => void
  onRenderComplete?: (svg: SVGElement) => void
  onRenderError?: (error: Error) => void
  className?: string
}

function MermaidDiagram({
  content,
  theme = 'auto',
  onRenderStart,
  onRenderComplete,
  onRenderError,
  className,
}: MermaidDiagramProps) {
  const containerRef = useRef<HTMLDivElement>(null)
  const instanceRef = useRef<MermaidDiagramVanilla | null>(null)
  const [, setRenderKey] = useState(0)

  const onRenderStartRef = useRef(onRenderStart)
  onRenderStartRef.current = onRenderStart
  const onRenderCompleteRef = useRef(onRenderComplete)
  onRenderCompleteRef.current = onRenderComplete
  const onRenderErrorRef = useRef(onRenderError)
  onRenderErrorRef.current = onRenderError

  useEffect(() => {
    const container = containerRef.current
    if (!container) return

    instanceRef.current = new MermaidDiagramVanilla({
      container,
      content,
      theme,
      onRenderStart: () => onRenderStartRef.current?.(),
      onRenderComplete: svg => {
        onRenderCompleteRef.current?.(svg)
        setRenderKey(k => k + 1)
      },
      onRenderError: err => onRenderErrorRef.current?.(err),
    })

    return () => {
      instanceRef.current?.destroy()
      instanceRef.current = null
    }
  }, [theme])

  // Update content
  useEffect(() => {
    if (instanceRef.current) {
      void instanceRef.current.update(content)
    }
  }, [content])

  return (
    <div
      ref={containerRef}
      data-slot="mermaid-diagram"
      className={cn('relative w-full overflow-auto', className)}
    />
  )
}
MermaidDiagram.displayName = 'MermaidDiagram'

export { MermaidDiagram }
