"use strict";
var __webpack_require__ = {};
(()=>{
    __webpack_require__.d = (exports1, definition)=>{
        for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
            enumerable: true,
            get: definition[key]
        });
    };
})();
(()=>{
    __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
})();
(()=>{
    __webpack_require__.r = (exports1)=>{
        if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
            value: 'Module'
        });
        Object.defineProperty(exports1, '__esModule', {
            value: true
        });
    };
})();
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
    SmartHandleProvider: ()=>SmartHandleProvider,
    SmartTargetHandle: ()=>SmartTargetHandle,
    SmartHandle: ()=>SmartHandle,
    SmartSourceHandle: ()=>SmartSourceHandle
});
const jsx_runtime_namespaceObject = require("react/jsx-runtime");
const react_namespaceObject = require("@xyflow/react");
const external_react_namespaceObject = require("react");
const CanvasEventBus_cjs_namespaceObject = require("../../utils/CanvasEventBus.cjs");
const CssUtil_cjs_namespaceObject = require("../../utils/CssUtil.cjs");
const external_ButtonHandleStyleUtils_cjs_namespaceObject = require("./ButtonHandleStyleUtils.cjs");
const external_HandleButton_cjs_namespaceObject = require("./HandleButton.cjs");
const external_HandleLabel_cjs_namespaceObject = require("./HandleLabel.cjs");
const external_HandleNotch_cjs_namespaceObject = require("./HandleNotch.cjs");
const external_useButtonHandleSizeAndPosition_cjs_namespaceObject = require("./useButtonHandleSizeAndPosition.cjs");
const SIDE_TO_POSITION = {
    top: react_namespaceObject.Position.Top,
    right: react_namespaceObject.Position.Right,
    bottom: react_namespaceObject.Position.Bottom,
    left: react_namespaceObject.Position.Left
};
const NEXT_SIDE_CLOCKWISE = {
    top: 'right',
    right: 'bottom',
    bottom: 'left',
    left: 'top'
};
const SmartHandleContext = /*#__PURE__*/ (0, external_react_namespaceObject.createContext)(null);
function SmartHandleProvider({ children, nodeWidth: _nodeWidth, nodeHeight: _nodeHeight }) {
    const registrationsRef = (0, external_react_namespaceObject.useRef)(new Map());
    const [version, setVersion] = (0, external_react_namespaceObject.useState)(0);
    const registerHandle = (0, external_react_namespaceObject.useCallback)((nodeId, registration)=>{
        if (!nodeId) return;
        const current = registrationsRef.current.get(nodeId) ?? [];
        const existingIndex = current.findIndex((r)=>r.handleId === registration.handleId && r.handleType === registration.handleType);
        const existing = existingIndex >= 0 ? current[existingIndex] : void 0;
        if (existing) {
            if (existing.computedPosition === registration.computedPosition && existing.configOrder === registration.configOrder) return;
            current[existingIndex] = registration;
        } else {
            current.push(registration);
            registrationsRef.current.set(nodeId, current);
        }
        setVersion((v)=>v + 1);
    }, []);
    const unregisterHandle = (0, external_react_namespaceObject.useCallback)((nodeId, handleId, handleType)=>{
        if (!nodeId) return;
        const current = registrationsRef.current.get(nodeId) ?? [];
        const filtered = current.filter((r)=>!(r.handleId === handleId && r.handleType === handleType));
        if (filtered.length === current.length) return;
        registrationsRef.current.set(nodeId, filtered);
        setVersion((v)=>v + 1);
    }, []);
    const getRegistrations = (0, external_react_namespaceObject.useCallback)(()=>registrationsRef.current, []);
    const contextValue = (0, external_react_namespaceObject.useMemo)(()=>({
            registerHandle,
            unregisterHandle,
            getRegistrations,
            version
        }), [
        registerHandle,
        unregisterHandle,
        getRegistrations,
        version
    ]);
    return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(SmartHandleContext.Provider, {
        value: contextValue,
        children: children
    });
}
function useSmartHandleContext() {
    return (0, external_react_namespaceObject.useContext)(SmartHandleContext);
}
function getHandleIndexOnSide(registrations, nodeId, handleId, handleType, position) {
    if (!nodeId) return {
        index: 0,
        total: 1
    };
    const nodeRegistrations = registrations.get(nodeId) ?? [];
    const handlesOnSide = nodeRegistrations.filter((r)=>r.computedPosition === position);
    const sorted = [
        ...handlesOnSide
    ].sort((a, b)=>a.configOrder - b.configOrder);
    const index = sorted.findIndex((r)=>r.handleId === handleId && r.handleType === handleType);
    return {
        index: index >= 0 ? index : 0,
        total: sorted.length
    };
}
function getNodeBounds(node) {
    const width = node.measured?.width || node.width || 150;
    const height = node.measured?.height || node.height || 40;
    const x = node.position.x;
    const y = node.position.y;
    return {
        x,
        y,
        width,
        height,
        centerX: x + width / 2,
        centerY: y + height / 2
    };
}
function calculateOptimalSide(currentBounds, connectedBounds) {
    const dx = connectedBounds.centerX - currentBounds.centerX;
    const dy = connectedBounds.centerY - currentBounds.centerY;
    const aspectRatio = currentBounds.width / currentBounds.height;
    const angle = Math.atan2(dy, dx);
    const degrees = 180 / Math.PI * angle;
    const threshold = 180 / Math.PI * Math.atan(1 / aspectRatio);
    if (degrees >= -threshold && degrees < threshold) return 'right';
    if (degrees >= threshold && degrees < 180 - threshold) return 'bottom';
    if (degrees >= 180 - threshold || degrees < -(180 - threshold)) return 'left';
    return 'top';
}
function findHandleConnections(edges, nodeId, handleId, handleType) {
    const connections = [];
    for (const edge of edges)if ('source' === handleType) {
        if (edge.source === nodeId) {
            const handleMatches = handleId ? edge.sourceHandle === handleId : !edge.sourceHandle;
            if (handleMatches) connections.push({
                connectedNodeId: edge.target,
                isSource: true
            });
        }
    } else if (edge.target === nodeId) {
        const handleMatches = handleId ? edge.targetHandle === handleId : !edge.targetHandle;
        if (handleMatches) connections.push({
            connectedNodeId: edge.source,
            isSource: false
        });
    }
    return connections;
}
const selectNodes = (state)=>state.nodes;
const selectEdges = (state)=>state.edges;
function findOptimalSidesForHandleType(edges, nodeId, handleType, currentBounds, nodeMap) {
    const handleSides = new Map();
    const relevantEdges = edges.filter((edge)=>'source' === handleType ? edge.source === nodeId : edge.target === nodeId);
    for (const edge of relevantEdges){
        const handleId = 'source' === handleType ? edge.sourceHandle : edge.targetHandle;
        const connectedNodeId = 'source' === handleType ? edge.target : edge.source;
        const connectedNode = nodeMap.get(connectedNodeId);
        if (connectedNode) {
            const connectedBounds = getNodeBounds(connectedNode);
            const optimalSide = calculateOptimalSide(currentBounds, connectedBounds);
            handleSides.set(handleId, optimalSide);
        }
    }
    return handleSides;
}
function useSmartPosition(nodeId, handleId, handleType, defaultPosition, hasSourceHandles) {
    const nodes = (0, react_namespaceObject.useStore)(selectNodes);
    const edges = (0, react_namespaceObject.useStore)(selectEdges);
    return (0, external_react_namespaceObject.useMemo)(()=>{
        if (!nodeId) return defaultPosition;
        const nodeMap = new Map();
        for (const node of nodes)nodeMap.set(node.id, node);
        const currentNode = nodeMap.get(nodeId);
        if (!currentNode) return defaultPosition;
        const connections = findHandleConnections(edges, nodeId, handleId, handleType);
        if (0 === connections.length) return defaultPosition;
        const currentBounds = getNodeBounds(currentNode);
        let optimalSide;
        if (1 === connections.length) {
            const firstConnection = connections[0];
            if (!firstConnection) return defaultPosition;
            const connectedNode = nodeMap.get(firstConnection.connectedNodeId);
            if (!connectedNode) return defaultPosition;
            const connectedBounds = getNodeBounds(connectedNode);
            optimalSide = calculateOptimalSide(currentBounds, connectedBounds);
        } else {
            let totalX = 0;
            let totalY = 0;
            let count = 0;
            for (const conn of connections){
                const connectedNode = nodeMap.get(conn.connectedNodeId);
                if (connectedNode) {
                    const bounds = getNodeBounds(connectedNode);
                    totalX += bounds.centerX;
                    totalY += bounds.centerY;
                    count++;
                }
            }
            if (0 === count) return defaultPosition;
            const avgBounds = {
                x: totalX / count,
                y: totalY / count,
                width: 0,
                height: 0,
                centerX: totalX / count,
                centerY: totalY / count
            };
            optimalSide = calculateOptimalSide(currentBounds, avgBounds);
        }
        if ('source' === handleType && 'left' === optimalSide) optimalSide = 'top';
        else if ('target' === handleType && 'right' === optimalSide && hasSourceHandles) optimalSide = 'bottom';
        if ('target' === handleType && hasSourceHandles) {
            const sourceSides = findOptimalSidesForHandleType(edges, nodeId, 'source', currentBounds, nodeMap);
            const adjustedSourceSides = new Set();
            for (const side of sourceSides.values())adjustedSourceSides.add('left' === side ? 'top' : side);
            adjustedSourceSides.add('right');
            if (adjustedSourceSides.has(optimalSide)) {
                let newSide = NEXT_SIDE_CLOCKWISE[optimalSide];
                let attempts = 0;
                while((adjustedSourceSides.has(newSide) || 'right' === newSide) && attempts < 3){
                    newSide = NEXT_SIDE_CLOCKWISE[newSide];
                    attempts++;
                }
                optimalSide = newSide;
            }
        }
        return SIDE_TO_POSITION[optimalSide];
    }, [
        nodeId,
        nodes,
        edges,
        handleId,
        handleType,
        defaultPosition,
        hasSourceHandles
    ]);
}
function SmartHandle({ type, id, defaultPosition = 'source' === type ? react_namespaceObject.Position.Right : react_namespaceObject.Position.Left, handleType = 'source' === type ? 'output' : 'input', style, className, nodeWidth, nodeHeight, label, labelIcon, labelBackgroundColor, showButton = false, selected = false, showNotches = true, onAction, visible = true, configOrder, ...rest }) {
    const nodeId = (0, react_namespaceObject.useNodeId)();
    const updateNodeInternals = (0, react_namespaceObject.useUpdateNodeInternals)();
    const [isHovered, setIsHovered] = (0, external_react_namespaceObject.useState)(false);
    const smartHandleContext = useSmartHandleContext();
    const handleRef = (0, external_react_namespaceObject.useRef)(null);
    const prevPositionRef = (0, external_react_namespaceObject.useRef)(null);
    const contextVersion = smartHandleContext?.version ?? 0;
    const hasSourceHandles = (0, external_react_namespaceObject.useMemo)(()=>{
        if (!nodeId || !smartHandleContext) return false;
        const registrations = smartHandleContext.getRegistrations();
        const nodeRegistrations = registrations.get(nodeId) ?? [];
        return nodeRegistrations.some((r)=>'source' === r.handleType);
    }, [
        nodeId,
        smartHandleContext,
        contextVersion
    ]);
    const computedPosition = useSmartPosition(nodeId, id, type, defaultPosition, hasSourceHandles);
    const isVertical = computedPosition === react_namespaceObject.Position.Top || computedPosition === react_namespaceObject.Position.Bottom;
    const registerHandle = smartHandleContext?.registerHandle;
    const unregisterHandle = smartHandleContext?.unregisterHandle;
    (0, external_react_namespaceObject.useEffect)(()=>{
        if (!nodeId || !registerHandle || !unregisterHandle) return;
        registerHandle(nodeId, {
            handleId: id,
            handleType: type,
            computedPosition,
            configOrder: configOrder ?? 0
        });
        return ()=>{
            unregisterHandle(nodeId, id, type);
        };
    }, [
        nodeId,
        id,
        type,
        computedPosition,
        registerHandle,
        unregisterHandle,
        configOrder
    ]);
    (0, external_react_namespaceObject.useEffect)(()=>{
        if (!nodeId) return;
        if (prevPositionRef.current !== computedPosition) {
            prevPositionRef.current = computedPosition;
            requestAnimationFrame(()=>{
                updateNodeInternals(nodeId);
            });
        }
    }, [
        nodeId,
        computedPosition,
        updateNodeInternals
    ]);
    const { index, total } = (0, external_react_namespaceObject.useMemo)(()=>{
        if (!nodeId || !smartHandleContext) return {
            index: 0,
            total: 1
        };
        const registrations = smartHandleContext.getRegistrations();
        return getHandleIndexOnSide(registrations, nodeId, id, type, computedPosition);
    }, [
        nodeId,
        id,
        type,
        computedPosition,
        contextVersion
    ]);
    const positionPercent = (0, external_react_namespaceObject.useMemo)(()=>{
        if (total <= 1) return 50;
        const relevantSize = isVertical ? nodeWidth : nodeHeight;
        if (relevantSize && relevantSize > 0) {
            const gridPositions = (0, external_ButtonHandleStyleUtils_cjs_namespaceObject.calculateGridAlignedHandlePositions)(relevantSize, total);
            const pixelPosition = gridPositions[index] ?? relevantSize / 2;
            return (0, external_ButtonHandleStyleUtils_cjs_namespaceObject.pixelToPercent)(pixelPosition, relevantSize);
        }
        return (index + 1) / (total + 1) * 100;
    }, [
        index,
        total,
        isVertical,
        nodeWidth,
        nodeHeight
    ]);
    const { width, height, top, bottom, left, right, transform } = (0, external_useButtonHandleSizeAndPosition_cjs_namespaceObject.useButtonHandleSizeAndPosition)({
        position: computedPosition,
        positionPercent,
        numHandles: total
    });
    const handleButtonClick = (0, external_react_namespaceObject.useCallback)((event)=>{
        event.stopPropagation();
        if (!nodeId) return;
        const actionEvent = {
            handleId: id ?? '',
            nodeId,
            handleType,
            position: computedPosition,
            originalEvent: event
        };
        onAction?.(actionEvent);
        CanvasEventBus_cjs_namespaceObject.canvasEventBus.emit('handle:action', {
            handleId: id ?? '',
            nodeId,
            handleType,
            position: computedPosition
        });
    }, [
        id,
        nodeId,
        handleType,
        computedPosition,
        onAction
    ]);
    return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(react_namespaceObject.Handle, {
        ref: handleRef,
        type: type,
        position: computedPosition,
        id: id,
        className: (0, CssUtil_cjs_namespaceObject.cx)('flex! items-center! justify-center! border-0! rounded-none! bg-transparent!', visible ? 'cursor-crosshair! pointer-events-auto!' : 'cursor-default! pointer-events-none!', className),
        isConnectable: visible && 'artifact' !== handleType,
        onMouseEnter: ()=>setIsHovered(true),
        onMouseLeave: ()=>setIsHovered(false),
        onMouseDown: ()=>setIsHovered(false),
        style: {
            width,
            height,
            top,
            bottom,
            left,
            right,
            transform,
            ...style
        },
        ...rest,
        children: visible && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsxs)(jsx_runtime_namespaceObject.Fragment, {
            children: [
                onAction && 'source' === type ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_HandleButton_cjs_namespaceObject.HandleButton, {
                    visible: showButton,
                    labelVisible: visible,
                    position: computedPosition,
                    onAction: handleButtonClick,
                    handleRef: handleRef,
                    label: label,
                    labelIcon: labelIcon,
                    labelBackgroundColor: labelBackgroundColor
                }) : label && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_HandleLabel_cjs_namespaceObject.HandleLabel, {
                    position: computedPosition,
                    backgroundColor: labelBackgroundColor,
                    label: label,
                    labelIcon: labelIcon
                }),
                /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_HandleNotch_cjs_namespaceObject.HandleNotch, {
                    handleType: handleType,
                    isVertical: isVertical,
                    selected: selected,
                    hovered: isHovered,
                    showNotch: showNotches
                })
            ]
        })
    });
}
function SmartSourceHandle(props) {
    return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(SmartHandle, {
        type: "source",
        handleType: "output",
        ...props
    });
}
function SmartTargetHandle(props) {
    return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(SmartHandle, {
        type: "target",
        handleType: "input",
        ...props
    });
}
exports.SmartHandle = __webpack_exports__.SmartHandle;
exports.SmartHandleProvider = __webpack_exports__.SmartHandleProvider;
exports.SmartSourceHandle = __webpack_exports__.SmartSourceHandle;
exports.SmartTargetHandle = __webpack_exports__.SmartTargetHandle;
for(var __rspack_i in __webpack_exports__)if (-1 === [
    "SmartHandle",
    "SmartHandleProvider",
    "SmartSourceHandle",
    "SmartTargetHandle"
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
Object.defineProperty(exports, '__esModule', {
    value: true
});
