import { useEffect, useRef } from 'react'

import { cn } from './utils'
import { FlowDiagram as FlowDiagramVanilla } from '../../visualization/flow-diagram'
import type { FlowNode, FlowEdge } from '../../visualization/flow-diagram/types'

export type { FlowNode, FlowEdge } from '../../visualization/flow-diagram/types'

export interface FlowDiagramProps {
  nodes: FlowNode[]
  edges: FlowEdge[]
  direction?: 'TB' | 'LR'
  zoomable?: boolean
  pannable?: boolean
  onNodeClick?: (node: FlowNode) => void
  onEdgeClick?: (edge: FlowEdge) => void
  className?: string
}

function FlowDiagram({
  nodes,
  edges,
  direction = 'TB',
  zoomable = true,
  pannable = true,
  onNodeClick,
  onEdgeClick,
  className,
}: FlowDiagramProps) {
  const containerRef = useRef<HTMLDivElement>(null)
  const instanceRef = useRef<FlowDiagramVanilla | null>(null)

  // Store latest callbacks in refs to avoid re-creating the instance
  const onNodeClickRef = useRef(onNodeClick)
  onNodeClickRef.current = onNodeClick
  const onEdgeClickRef = useRef(onEdgeClick)
  onEdgeClickRef.current = onEdgeClick

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

    instanceRef.current = new FlowDiagramVanilla({
      container,
      nodes,
      edges,
      direction,
      zoomable,
      pannable,
      onNodeClick: node => onNodeClickRef.current?.(node),
      onEdgeClick: edge => onEdgeClickRef.current?.(edge),
    })

    return () => {
      instanceRef.current?.destroy()
      instanceRef.current = null
    }
    // Only re-create on structural props; callbacks are handled via refs
  }, [direction, zoomable, pannable])

  // Update data without full re-mount
  useEffect(() => {
    if (instanceRef.current) {
      instanceRef.current.update(nodes, edges)
    }
  }, [nodes, edges])

  return (
    <div
      ref={containerRef}
      data-slot="flow-diagram"
      className={cn('relative h-full w-full overflow-hidden', className)}
    />
  )
}
FlowDiagram.displayName = 'FlowDiagram'

export { FlowDiagram }
