import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import { Handle, Position } from "../../xyflow/react.js";
import { memo, useCallback, useMemo, useRef, useState } from "react";
import { canvasEventBus } from "../../utils/CanvasEventBus.js";
import { cx } from "../../utils/CssUtil.js";
import { getHandleActionPortal, getInwardHandleLayout } from "./ButtonHandleLayoutUtils.js";
import { calculateGridAlignedHandlePositions, pixelToPercent } from "./ButtonHandleStyleUtils.js";
import { HandleButton, HandleHoverBridge } from "./HandleButton.js";
import { HandleLabel } from "./HandleLabel.js";
import { HandleNotch } from "./HandleNotch.js";
import { useButtonHandleSizeAndPosition } from "./useButtonHandleSizeAndPosition.js";
const ButtonHandleBase = ({ id, nodeId, type, position, connectionPosition = position, handleType, label, labelIcon, labelBackgroundColor, visible = true, showButton = true, selected = false, index = 0, total = 1, onAction, showNotches = true, customPositionAndOffsets, nodeWidth, nodeHeight, portalAction = false })=>{
    const handleRef = useRef(null);
    const [isHovered, setIsHovered] = useState(false);
    const isVertical = position === Position.Top || position === Position.Bottom;
    const positionPercent = useMemo(()=>{
        const relevantSize = isVertical ? nodeWidth : nodeHeight;
        if (relevantSize && relevantSize > 0) {
            const gridPositions = calculateGridAlignedHandlePositions(relevantSize, total);
            const pixelPosition = gridPositions[index] ?? relevantSize / 2;
            return pixelToPercent(pixelPosition, relevantSize);
        }
        return (index + 1) / (total + 1) * 100;
    }, [
        index,
        total,
        isVertical,
        nodeWidth,
        nodeHeight
    ]);
    const handleButtonClick = useCallback((event)=>{
        event.stopPropagation();
        const actionEvent = {
            handleId: id,
            nodeId,
            handleType,
            position: connectionPosition,
            originalEvent: event
        };
        onAction?.(actionEvent);
        canvasEventBus.emit('handle:action', {
            handleId: id,
            nodeId,
            handleType,
            position: connectionPosition
        });
    }, [
        connectionPosition,
        id,
        nodeId,
        handleType,
        onAction
    ]);
    const markAsHovered = useCallback(()=>setIsHovered(true), []);
    const unmarkAsHovered = useCallback(()=>setIsHovered(false), []);
    const showActionButton = !!onAction && 'source' === type;
    const { width: handleWidth, height: handleHeight, top, bottom, left, right, transform } = useButtonHandleSizeAndPosition({
        position,
        positionPercent,
        numHandles: total,
        customPositionAndOffsets
    });
    if (connectionPosition !== position) {
        const layout = getInwardHandleLayout(position, handleType);
        return /*#__PURE__*/ jsxs("div", {
            className: cx('absolute flex overflow-visible', visible ? 'pointer-events-auto opacity-100' : 'pointer-events-none opacity-0'),
            style: {
                top,
                bottom,
                left,
                right,
                transform: layout.rootTransform
            },
            onMouseEnter: markAsHovered,
            onMouseLeave: unmarkAsHovered,
            onMouseDown: unmarkAsHovered,
            children: [
                /*#__PURE__*/ jsx(InwardHandleContent, {
                    handleType: handleType,
                    isVertical: isVertical,
                    selected: selected,
                    hovered: isHovered,
                    showNotch: showNotches,
                    label: label,
                    labelIcon: labelIcon,
                    labelBackgroundColor: labelBackgroundColor,
                    layout: layout
                }),
                /*#__PURE__*/ jsx(Handle, {
                    ref: handleRef,
                    type: type,
                    position: connectionPosition,
                    id: id,
                    onMouseEnter: markAsHovered,
                    onMouseLeave: unmarkAsHovered,
                    onMouseDown: unmarkAsHovered,
                    className: cx('absolute! z-20 flex! items-center! justify-center! overflow-visible! border-0! rounded-none! bg-transparent!', visible ? 'cursor-crosshair! pointer-events-auto! opacity-100' : 'cursor-default! pointer-events-none! opacity-0'),
                    style: layout.anchorStyle
                }),
                showActionButton ? /*#__PURE__*/ jsx(HandleButton, {
                    visible: showButton,
                    labelVisible: visible,
                    position: connectionPosition,
                    onAction: handleButtonClick,
                    handleRef: handleRef
                }) : null
            ]
        });
    }
    const portal = showActionButton && portalAction && !customPositionAndOffsets ? getHandleActionPortal({
        nodeId,
        position,
        positionPercent,
        total,
        nodeWidth,
        nodeHeight
    }) : void 0;
    return /*#__PURE__*/ jsxs(Handle, {
        ref: handleRef,
        type: type,
        position: position,
        id: id,
        onMouseEnter: markAsHovered,
        onMouseLeave: unmarkAsHovered,
        onMouseDown: unmarkAsHovered,
        className: cx('flex! items-center! justify-center! border-0! rounded-none! bg-transparent!', visible ? 'cursor-crosshair! pointer-events-auto! opacity-100' : 'cursor-default! pointer-events-none! opacity-0'),
        style: {
            width: handleWidth,
            height: handleHeight,
            top,
            bottom,
            left,
            right,
            transform
        },
        children: [
            /*#__PURE__*/ jsx(HandleNotch, {
                handleType: handleType,
                isVertical: isVertical,
                selected: selected,
                hovered: isHovered,
                showNotch: showNotches
            }),
            showActionButton ? /*#__PURE__*/ jsx(HandleButton, {
                visible: showButton,
                labelVisible: visible,
                position: position,
                onAction: handleButtonClick,
                handleRef: handleRef,
                label: label,
                labelIcon: labelIcon,
                labelBackgroundColor: labelBackgroundColor,
                portal: portal
            }) : label && /*#__PURE__*/ jsx(HandleLabel, {
                position: position,
                backgroundColor: labelBackgroundColor,
                label: label,
                labelIcon: labelIcon
            })
        ]
    });
};
const ButtonHandle = /*#__PURE__*/ memo(ButtonHandleBase);
function InwardHandleContent({ handleType, isVertical, selected, hovered, showNotch, label, labelIcon, labelBackgroundColor, layout }) {
    const labelElement = label ? /*#__PURE__*/ jsxs("div", {
        className: cx('pointer-events-none flex items-center gap-1.5 whitespace-nowrap rounded-full border border-border-subtle bg-transparent px-2 py-0.5', 'text-xs font-medium leading-4 text-foreground-muted'),
        style: labelBackgroundColor ? {
            backgroundColor: labelBackgroundColor
        } : void 0,
        children: [
            labelIcon,
            /*#__PURE__*/ jsx("span", {
                children: label
            })
        ]
    }) : null;
    const notchElement = /*#__PURE__*/ jsx("span", {
        className: "relative z-10 flex shrink-0",
        style: layout.notchStyle,
        children: /*#__PURE__*/ jsx(HandleNotch, {
            handleType: handleType,
            isVertical: isVertical,
            selected: selected,
            hovered: hovered,
            showNotch: showNotch
        })
    });
    return /*#__PURE__*/ jsxs("div", {
        className: cx('flex items-center', layout.contentDirectionClassName),
        children: [
            labelElement,
            notchElement
        ]
    });
}
const ButtonHandlesBase = ({ nodeId, handles, position, connectionPosition = position, selected = false, hovered = false, visible = true, showAddButton = true, showNotches = true, customPositionAndOffsets, shouldShowAddButtonFn = ({ showAddButton, selected, hovered })=>showAddButton && (selected || hovered), nodeWidth, nodeHeight, portalActions = false })=>{
    const finalSelected = shouldShowAddButtonFn({
        showAddButton,
        selected,
        hovered
    });
    const visibleHandles = handles.filter((h)=>h.visible ?? true);
    const hasSourceButtons = visibleHandles.some((h)=>'source' === h.type && h.onAction);
    return /*#__PURE__*/ jsxs(Fragment, {
        children: [
            /*#__PURE__*/ jsx(HandleHoverBridge, {
                position: connectionPosition,
                visible: hasSourceButtons && finalSelected
            }),
            visibleHandles.map((handle, index)=>{
                const handleVisible = handle.showHandle ?? visible;
                return /*#__PURE__*/ jsx(ButtonHandle, {
                    id: handle.id,
                    nodeId: nodeId,
                    type: handle.type,
                    position: position,
                    connectionPosition: connectionPosition,
                    handleType: handle.handleType,
                    label: handle.label,
                    labelIcon: handle.labelIcon,
                    labelBackgroundColor: handle.labelBackgroundColor,
                    index: index,
                    total: visibleHandles.length,
                    selected: selected,
                    visible: handleVisible,
                    showButton: finalSelected && handleVisible && handle.showButton,
                    onAction: handle.onAction,
                    showNotches: showNotches,
                    customPositionAndOffsets: customPositionAndOffsets,
                    nodeWidth: nodeWidth,
                    nodeHeight: nodeHeight,
                    portalAction: portalActions && 'source' === handle.type
                }, handle.id);
            })
        ]
    });
};
const ButtonHandles = /*#__PURE__*/ memo(ButtonHandlesBase);
export { ButtonHandle, ButtonHandles };
