import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import { Position } from "../../xyflow/react.js";
import { memo, useCallback, useRef, useState } from "react";
import { isPreviewEdge } from "../../utils/createPreviewNode.js";
import { useBaseCanvasMode } from "../BaseCanvas/BaseCanvasModeProvider.js";
import { EdgeToolbar, useEdgeToolbarState } from "../Toolbar/index.js";
import { areEdgePropsEqual } from "./shared/areEdgePropsEqual.js";
import { EMPTY_WAYPOINTS } from "./shared/constants.js";
import { isSegmentInteractable, isSegmentPerpendicular } from "./shared/geometry.js";
import { useEdgeGeometry, useExecutionEdge, useNodeDragRebalance, useWaypointEditor } from "./shared/hooks/index.js";
import { EdgeArrow, EdgeLabel, EdgePath, SegmentDragHandle, WaypointHandle } from "./shared/primitives/index.js";
import { resolveEdgeColor } from "./shared/resolveEdgeColor.js";
const CanvasEdge_CanvasEdge = /*#__PURE__*/ memo(function({ id, selected, animated, source, target, sourceX, sourceY, sourcePosition = Position.Right, targetX, targetY, targetPosition = Position.Left, sourceHandleId, targetHandleId, style, data }) {
    const isReadOnly = 'readonly' === useBaseCanvasMode().mode;
    const [isHovered, setIsHovered] = useState(false);
    const onMouseEnter = useCallback(()=>setIsHovered(true), []);
    const onMouseLeave = useCallback(()=>setIsHovered(false), []);
    const pathRef = useRef(null);
    const routing = data?.routing ?? 'waypoint';
    const storedWaypoints = data?.waypoints ?? EMPTY_WAYPOINTS;
    const strokeStyle = data?.strokeStyle ?? 'solid';
    const hideArrowHead = !!data?.hideArrowHead;
    const label = data?.label;
    const editingEnabled = !!data?.enableEditing && 'waypoint' === routing && !isReadOnly;
    const waypoints = useNodeDragRebalance({
        edgeId: id,
        source,
        target,
        sourceX,
        sourceY,
        sourcePosition,
        targetX,
        targetY,
        targetPosition,
        waypoints: storedWaypoints,
        enabled: editingEnabled,
        onChange: data?.onWaypointsChange
    });
    const routedWaypoints = data?.routedWaypoints ?? EMPTY_WAYPOINTS;
    const effectiveWaypoints = waypoints.length > 0 ? waypoints : routedWaypoints;
    const executionEnabled = !!data?.enableExecution;
    const toolbarEnabled = !!data?.enableToolbar && !isReadOnly;
    const previewEdge = isPreviewEdge({
        id,
        source,
        target
    });
    const geometry = useEdgeGeometry({
        routing,
        sourceNodeId: source,
        targetNodeId: target,
        sourceHandleId,
        targetHandleId,
        sourceX,
        sourceY,
        sourcePosition,
        targetX,
        targetY,
        targetPosition,
        waypoints: effectiveWaypoints,
        enableSegments: editingEnabled,
        hideArrowHead
    });
    const editor = useWaypointEditor({
        edgeId: id,
        waypoints,
        pathPoints: geometry.pathPoints,
        enabled: editingEnabled,
        onChange: data?.onWaypointsChange
    });
    const execution = useExecutionEdge({
        edgeId: id,
        target,
        edgePath: geometry.edgePath,
        enabled: executionEnabled
    });
    const isDiffRemoved = data?.isDiffRemoved ?? false;
    const color = resolveEdgeColor({
        selected,
        isHovered,
        isInvalid: data?.isInvalid ?? false,
        isDiffAdded: data?.isDiffAdded ?? false,
        isDiffRemoved,
        previewEdge,
        statusColor: execution.statusColor
    });
    const toolbar = useEdgeToolbarState({
        edgeId: id,
        pathElementRef: pathRef,
        isHovered: toolbarEnabled && isHovered,
        source,
        target,
        sourceHandleId,
        targetHandleId,
        sourcePosition,
        targetPosition
    });
    const showEditingChrome = editingEnabled && (isHovered || selected || editor.isDragging);
    const opacity = style?.opacity ?? 1;
    return /*#__PURE__*/ jsxs(Fragment, {
        children: [
            /*#__PURE__*/ jsxs("g", {
                onMouseEnter: onMouseEnter,
                onMouseLeave: onMouseLeave,
                onMouseMove: toolbarEnabled ? toolbar.handleMouseMoveOnPath : void 0,
                children: [
                    /*#__PURE__*/ jsx(EdgePath, {
                        id: id,
                        d: geometry.edgePath,
                        color: color,
                        selected: selected,
                        animated: animated,
                        strokeStyle: previewEdge || isDiffRemoved ? 'dashed' : strokeStyle,
                        isReadOnly: isReadOnly,
                        style: style,
                        opacity: opacity,
                        pathRef: pathRef
                    }),
                    showEditingChrome && geometry.segments.map((segment, index)=>{
                        if (!isSegmentInteractable(segment) || !isSegmentPerpendicular(segment)) return null;
                        return /*#__PURE__*/ jsx(SegmentDragHandle, {
                            segment: segment,
                            segmentIndex: index,
                            handlers: editor.segmentHandlers
                        }, segment.id);
                    }),
                    editingEnabled && waypoints.map((waypoint, index)=>/*#__PURE__*/ jsx(WaypointHandle, {
                            waypoint: waypoint,
                            index: index,
                            forceVisible: showEditingChrome,
                            handlers: editor.waypointHandlers
                        }, waypoint.id)),
                    !hideArrowHead && /*#__PURE__*/ jsx(EdgeArrow, {
                        target: {
                            x: targetX,
                            y: targetY
                        },
                        angle: geometry.arrow.angle,
                        offset: geometry.arrow.offset,
                        color: color,
                        opacity: opacity
                    }),
                    execution.animation,
                    'string' == typeof label && label.length > 0 && /*#__PURE__*/ jsx(EdgeLabel, {
                        x: geometry.labelPoint.x,
                        y: geometry.labelPoint.y,
                        text: label,
                        selected: selected
                    })
                ]
            }),
            toolbarEnabled && toolbar.showToolbar && toolbar.toolbarPositioning && /*#__PURE__*/ jsx(EdgeToolbar, {
                edgeId: id,
                visible: toolbar.showToolbar,
                positioning: toolbar.toolbarPositioning,
                config: toolbar.config,
                onMouseEnter: onMouseEnter,
                onMouseLeave: onMouseLeave
            })
        ]
    });
}, areEdgePropsEqual);
export { CanvasEdge_CanvasEdge as CanvasEdge };
