/**
 * @license MIT
 * author: Cube Dev Team
 * @cube-dev/ui-kit v0.0.0-canary-43d3dd9
 * Released under the MIT license.
 */

import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { PressResponder } from '@react-aria/interactions';
import { useDOMRef, useIsMobileDevice } from '@react-spectrum/utils';
import { forwardRef, Fragment, useEffect, useMemo, useRef, } from 'react';
import { DismissButton, useMenuTrigger, useOverlayPosition, } from 'react-aria';
import { useMenuTriggerState } from 'react-stately';
import { generateRandomId } from '../../../utils/random.js';
import { SlotProvider } from '../../../utils/react/index.js';
import { useEventBus } from '../../../utils/react/useEventBus.js';
import { Popover, Tray } from '../../overlays/Modal/index.js';
import { MenuContext } from './context.js';
function MenuTrigger(props, ref) {
    const menuPopoverRef = useRef(null);
    const triggerRef = useRef(null);
    const domRef = useDOMRef(ref);
    const menuTriggerRef = props.targetRef || domRef || triggerRef;
    const menuRef = useRef(null);
    const wasOpenRef = useRef(false);
    const { children, shouldFlip = true, closeOnSelect, trigger = 'press', isDisabled, isDummy, } = props;
    // Generate a unique ID for this menu instance
    const menuId = useMemo(() => generateRandomId(), []);
    // Get event bus for menu synchronization
    const { emit, on } = useEventBus();
    if (!Array.isArray(children) || children.length > 2) {
        throw new Error('MenuTrigger must have exactly 2 children');
    }
    let [menuTrigger, menu] = children;
    const state = useMenuTriggerState(props);
    // Listen for other menus opening and close this one if needed
    useEffect(() => {
        const unsubscribe = on('popover:open', (data) => {
            // If another menu is opening and this menu is open, close this one
            if (data.menuId !== menuId && state.isOpen && !isDummy) {
                state.close();
            }
        });
        return unsubscribe;
    }, [on, menuId, state]);
    // Emit event when this menu opens
    useEffect(() => {
        if (state.isOpen && !isDummy) {
            emit('popover:open', { menuId });
        }
    }, [state.isOpen, emit, menuId, isDummy]);
    // Restore focus manually when the menu closes
    useEffect(() => {
        if (!state.isOpen && wasOpenRef.current && !isDummy) {
            wasOpenRef.current = false;
            // Use setTimeout to ensure focus restoration happens after any animations
            setTimeout(() => {
                menuTriggerRef.current?.focus();
            }, 0);
        }
        else if (state.isOpen) {
            wasOpenRef.current = true;
        }
    }, [state.isOpen, menuTriggerRef, isDummy]);
    if (typeof menuTrigger === 'function') {
        menuTrigger = menuTrigger(state);
    }
    const { menuTriggerProps, menuProps } = useMenuTrigger({ isDisabled }, state, menuTriggerRef);
    let initialPlacement = props.placement ?? 'bottom start';
    const isMobile = useIsMobileDevice();
    const { overlayProps: positionProps, placement } = useOverlayPosition({
        targetRef: menuTriggerRef,
        overlayRef: menuPopoverRef,
        scrollRef: menuRef,
        placement: initialPlacement,
        shouldFlip: shouldFlip,
        isOpen: state.isOpen && !isMobile,
        onClose: state.close,
        containerPadding: props.containerPadding,
        offset: props.offset ?? 8,
        crossOffset: props.crossOffset ?? 0,
    });
    const menuContext = {
        ...menuProps,
        ref: menuRef,
        onClose: state.close,
        closeOnSelect,
        autoFocus: state.focusStrategy ?? 'first',
        style: isMobile
            ? {
                width: '100%',
                maxHeight: 'inherit',
            }
            : undefined,
        mods: {
            popover: !isMobile,
            tray: isMobile,
        },
        isClosing: !state.isOpen,
    };
    const contents = (_jsxs(_Fragment, { children: [_jsx(DismissButton, { onDismiss: state.close }), menu, _jsx(DismissButton, { onDismiss: state.close })] }));
    // On small screen devices, the menu is rendered in a tray, otherwise a popover.
    let overlay;
    if (isMobile) {
        overlay = (_jsx(Tray, { isOpen: state.isOpen, onClose: state.close, children: contents }));
    }
    else {
        overlay = (_jsx(Popover, { ref: menuPopoverRef, hideArrow: true, isNonModal: true, isOpen: state.isOpen, style: positionProps.style, placement: placement, shouldCloseOnInteractOutside: (el) => {
                const menuTriggerEl = el.closest('[data-popover-trigger]');
                // If no menu trigger was clicked, allow closing
                if (!menuTriggerEl)
                    return true;
                // For dummy triggers (like useAnchoredMenu), check if the clicked element
                // is the target element or its descendant
                if (isDummy &&
                    (menuTriggerEl === menuTriggerRef.current ||
                        menuTriggerRef.current?.contains(el))) {
                    return true;
                }
                // If the same trigger that opened this menu was clicked, allow closing
                if (menuTriggerEl === menuTriggerRef.current)
                    return true;
                // Otherwise, don't close (let event mechanism handle it)
                return false;
            }, onClose: state.close, children: contents }));
    }
    return (_jsxs(Fragment, { children: [_jsx(SlotProvider, { slots: { actionButton: { holdAffordance: trigger === 'longPress' } }, children: !isDummy ? (_jsx(PressResponder, { ...menuTriggerProps, ref: menuTriggerRef, "data-popover-trigger": true, isPressed: state.isOpen, children: menuTrigger })) : null }), _jsx(MenuContext.Provider, { value: menuContext, children: overlay })] }));
}
/**
 * The MenuTrigger serves as a wrapper around a Menu and its associated trigger,
 * linking the Menu's open state with the trigger's press state.
 */
let _MenuTrigger = forwardRef(MenuTrigger);
_MenuTrigger.displayName = 'MenuTrigger';
export { _MenuTrigger as MenuTrigger };

        