import React, { useContext, useMemo } from 'react'
import {
  BaseEdge,
  getBezierPath,
  type EdgeProps,
} from '@xyflow/react'
import FlowContext from '../../lib/flowContext'

const EDGE_STROKE_WIDTH = 2
const DOT_MARKER_R = 1.5

function getEdgeLabelByTargetType(targetType: string | undefined): string | undefined {
  if (targetType === 'render') return 'render'
  if (targetType === 'config') return 'add input'
  return undefined
}

export function AnimatedEdge({
  id,
  sourceX,
  sourceY,
  targetX,
  targetY,
  sourcePosition,
  targetPosition,
  style,
  label: labelProp,
  interactionWidth,
  target,
}: EdgeProps) {
  const ctx = useContext(FlowContext)
  const nodes = ctx?.nodes ?? []
  const targetNode = useMemo(() => nodes.find((n: any) => n.id === target), [nodes, target])
  const derivedLabel = useMemo(
    () => getEdgeLabelByTargetType(targetNode?.type),
    [targetNode?.type]
  )
  const label = labelProp ?? derivedLabel

  const [edgePath, edgeLabelX, edgeLabelY] = getBezierPath({
    sourceX,
    sourceY,
    targetX,
    targetY,
    sourcePosition,
    targetPosition,
  })

  const startId = `animated-edge-dot-start-${id}`
  const endId = `animated-edge-dot-end-${id}`

  return (
    <>
      <defs>
        <marker
          id={startId}
          markerWidth={DOT_MARKER_R * 2}
          markerHeight={DOT_MARKER_R * 2}
          refX={DOT_MARKER_R - 1}
          refY={DOT_MARKER_R}
          orient="auto"
        >
          <circle
            r={DOT_MARKER_R}
            cx={DOT_MARKER_R}
            cy={DOT_MARKER_R}
            className="fill-primary stroke-background"
            strokeWidth={2}
          />
        </marker>
        <marker
          id={endId}
          markerWidth={DOT_MARKER_R * 2}
          markerHeight={DOT_MARKER_R * 2}
          refX={DOT_MARKER_R + 1}
          refY={DOT_MARKER_R}
          orient="auto"
        >
          <circle
            r={DOT_MARKER_R}
            cx={DOT_MARKER_R}
            cy={DOT_MARKER_R}
            className="fill-primary stroke-background"
            strokeWidth={2}
          />
        </marker>
      </defs>
      <BaseEdge
        path={edgePath}
        markerStart={`url(#${startId})`}
        markerEnd={`url(#${endId})`}
        style={{
          strokeWidth: EDGE_STROKE_WIDTH,
          ...style,
        }}
        className="animated-edge-path"
        interactionWidth={interactionWidth}
      />
      {label != null && (
        <g transform={`translate(${edgeLabelX}, ${edgeLabelY})`} className="nodrag nopan">
          <rect
            x={-32}
            y={-9}
            width={64}
            height={18}
            rx={4}
            ry={4}
            className="fill-background stroke-border"
            strokeWidth={1}
          />
          <text
            textAnchor="middle"
            dominantBaseline="middle"
            className="fill-foreground text-[10px] font-medium"
          >
            {label}
          </text>
        </g>
      )}
    </>
  )
}
