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

import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useSyncRef } from '@react-aria/utils';
import React, { useEffect, useMemo, useRef, } from 'react';
import { DismissButton, useMenuTrigger, useOverlayPosition, } from 'react-aria';
import { useMenuTriggerState } from 'react-stately';
import { generateRandomId } from '../../../utils/random.js';
import { useEventBus } from '../../../utils/react/useEventBus.js';
import { Popover } from '../../overlays/Modal/index.js';
import { MenuContext, useMenuContext } from './context.js';
import { SubmenuTriggerContext } from './SubmenuTriggerContext.js';
// Default placement & offset for sub-menus (matches Spectrum / Aria)
const DEFAULT_PLACEMENT = 'right top';
const DEFAULT_OFFSET = 4;
const DEFAULT_CROSS_OFFSET = -5;
/**
 * Internal SubMenuTrigger that receives the already-rendered trigger element
 * from the collection system and wraps it with submenu behavior.
 */
function InternalSubMenuTrigger(props) {
    const { children, placement = DEFAULT_PLACEMENT, offset = DEFAULT_OFFSET, crossOffset = DEFAULT_CROSS_OFFSET, shouldFlip = true, isDisabled, autoFocus = 'first', onAction, targetKey, ...overlayProps } = props;
    // Children: [menuTrigger (already rendered MenuItem), menu (Menu component)]
    const [menuTrigger, menu] = React.Children.toArray(children);
    const state = useMenuTriggerState(props);
    // Generate a unique ID for this submenu instance
    const submenuId = useMemo(() => generateRandomId(), []);
    // Get event bus for submenu synchronization
    const { emit, on } = useEventBus();
    // Refs – trigger (MenuItem <li>) and overlay (<div> from Popover)
    const domTriggerRef = useRef(null);
    const popoverRef = useRef(null);
    const menuRef = useRef(null);
    // Strip keyboard/press handlers that we will implement ourselves
    const { menuTriggerProps: rawTriggerProps, menuProps } = useMenuTrigger({ type: 'submenu', isDisabled }, state, domTriggerRef);
    // Get parent context to check if parent menu is closing
    const parentContext = useMenuContext();
    // Remove default onKeyDown/onPress handlers from trigger props – we implement custom ones
    const { onKeyDown: _mtOnKeyDown, onPress: _mtOnPress, onPressStart: _mtOnPressStart, onKeyUp: _mtOnKeyUp, ...menuTriggerProps } = rawTriggerProps;
    const { overlayProps: positionProps } = useOverlayPosition({
        targetRef: domTriggerRef,
        overlayRef: popoverRef,
        scrollRef: menuRef,
        placement,
        offset: offset,
        crossOffset: crossOffset,
        shouldFlip,
        isOpen: state.isOpen,
        onClose: state.close,
    });
    /**
     * Build a MenuContext for the nested menu so it behaves just like a regular
     * popover-based Menu (selection handling, focus management, etc.).
     */
    const nestedMenuContext = useMemo(() => {
        const ctx = {
            ...menuProps,
            ref: menuRef,
            // Pass the parent's onClose to close the entire menu hierarchy
            onClose: () => {
                // Close this submenu state immediately
                state.close();
                // Then close the parent menu
                if (parentContext.onClose) {
                    parentContext.onClose();
                }
            },
            closeOnSelect: true,
            autoFocus,
            mods: {
                popover: true,
            },
            // Propagate closing state from parent
            isClosing: parentContext.isClosing || !state.isOpen,
        };
        return ctx;
    }, [
        menuProps,
        autoFocus,
        state,
        parentContext.onClose,
        parentContext.isClosing,
    ]);
    // Sync the parent selection manager focus with DOM ref (for virtual focus scenarios)
    useSyncRef(parentContext, domTriggerRef);
    // Listen for other menus opening and close this submenu if needed
    useEffect(() => {
        const unsubscribe = on('popover:open', (data) => {
            // If another menu is opening and this submenu is open, close this one
            if (data.menuId !== submenuId && state.isOpen) {
                state.close();
            }
        });
        return unsubscribe;
    }, [on, submenuId, state]);
    // Emit event when this submenu opens
    useEffect(() => {
        if (state.isOpen) {
            emit('popover:open', { menuId: submenuId });
        }
    }, [state.isOpen, emit, submenuId]);
    // Cleanup hover timers and reset refs on unmount
    useEffect(() => {
        return () => {
            if (hoverOpenTimerRef.current) {
                clearTimeout(hoverOpenTimerRef.current);
            }
            if (hoverCloseTimerRef.current) {
                clearTimeout(hoverCloseTimerRef.current);
            }
            isHoveringRef.current = false;
            isHoveringSubmenuRef.current = false;
        };
    }, []);
    // ----- Render -----
    // Handle keyboard navigation
    const handleKeyDown = (e) => {
        if (isDisabled)
            return;
        // Arrow right opens submenu
        if (e.key === 'ArrowRight') {
            e.preventDefault();
            e.stopPropagation();
            state.open();
        }
        // Enter or Space opens submenu (suppress subsequent onAction)
        else if (e.key === 'Enter' || e.key === ' ') {
            e.preventDefault();
            e.stopPropagation();
            // Stop immediate propagation to prevent React Aria's handlers from running
            e.nativeEvent.stopImmediatePropagation();
            state.open();
            suppressNextActionRef.current = true; // Remember it was keyboard
        }
        // Arrow left closes submenu if open
        else if (e.key === 'ArrowLeft' && state.isOpen) {
            e.preventDefault();
            e.stopPropagation();
            state.close();
        }
    };
    // Use refs to store timer IDs
    const hoverOpenTimerRef = useRef(null);
    const hoverCloseTimerRef = useRef(null);
    // Track if mouse is over trigger or submenu
    const isHoveringRef = useRef(false);
    const isHoveringSubmenuRef = useRef(false);
    // Track whether the next onAction comes from a keyboard press
    const suppressNextActionRef = useRef(false);
    const checkShouldClose = () => {
        // Only close if mouse is not over trigger OR submenu
        if (!isHoveringRef.current && !isHoveringSubmenuRef.current) {
            hoverCloseTimerRef.current = setTimeout(() => {
                // Double check before closing
                if (!isHoveringRef.current && !isHoveringSubmenuRef.current) {
                    state.close();
                }
            }, 300);
        }
    };
    // Handle mouse interactions on trigger
    const handleMouseEnter = () => {
        if (isDisabled)
            return;
        isHoveringRef.current = true;
        // Clear any pending close timer
        if (hoverCloseTimerRef.current) {
            clearTimeout(hoverCloseTimerRef.current);
            hoverCloseTimerRef.current = null;
        }
        // Use a small delay to prevent accidental opens
        if (!state.isOpen) {
            hoverOpenTimerRef.current = setTimeout(() => {
                if (isHoveringRef.current) {
                    state.open();
                }
            }, 200);
        }
    };
    const handleMouseLeave = () => {
        isHoveringRef.current = false;
        // Clear open timer if it exists
        if (hoverOpenTimerRef.current) {
            clearTimeout(hoverOpenTimerRef.current);
            hoverOpenTimerRef.current = null;
        }
        // Check if we should close
        checkShouldClose();
    };
    // Handle mouse events on the submenu popover
    const handlePopoverMouseEnter = () => {
        isHoveringSubmenuRef.current = true;
        // Clear any pending close timer when entering submenu
        if (hoverCloseTimerRef.current) {
            clearTimeout(hoverCloseTimerRef.current);
            hoverCloseTimerRef.current = null;
        }
    };
    const handlePopoverMouseLeave = () => {
        isHoveringSubmenuRef.current = false;
        // Check if we should close
        checkShouldClose();
    };
    // Merge event handlers
    const mergeHandler = (handler1, handler2) => {
        return (...args) => {
            handler1?.(...args);
            handler2?.(...args);
        };
    };
    // Provide context to the trigger element (already rendered MenuItem)
    const triggerContextValue = useMemo(() => ({
        triggerRef: domTriggerRef,
        triggerProps: menuTriggerProps,
        isOpen: state.isOpen,
        isDisabled,
        onMouseEnter: handleMouseEnter,
        onMouseLeave: handleMouseLeave,
        onKeyDown: handleKeyDown,
        onAction: isDisabled
            ? undefined
            : () => {
                // Ignore the synthetic press generated by the same Enter/Space
                if (suppressNextActionRef.current) {
                    suppressNextActionRef.current = false;
                    return;
                }
                // This is a mouse click, open the submenu
                state.open();
            },
    }), [
        state,
        isDisabled,
        handleMouseEnter,
        handleMouseLeave,
        handleKeyDown,
        menuTriggerProps,
    ]);
    return (_jsxs(_Fragment, { children: [_jsx(SubmenuTriggerContext.Provider, { value: triggerContextValue, children: menuTrigger }), state.isOpen && (_jsx(Popover, { ref: popoverRef, hideArrow: true, isNonModal: true, isOpen: !parentContext.isClosing, style: positionProps.style, placement: placement, onClose: state.close, ...overlayProps, children: _jsxs("div", { style: { display: 'contents' }, onMouseEnter: handlePopoverMouseEnter, onMouseLeave: handlePopoverMouseLeave, children: [_jsx(DismissButton, { onDismiss: state.close }), _jsx(MenuContext.Provider, { value: nestedMenuContext, children: React.cloneElement(menu, {
                                ...menu.props,
                                autoFocus,
                                onAction: (key) => {
                                    // Call original menu onAction first
                                    menu.props.onAction?.(key);
                                    onAction?.(key);
                                    // Don't close here - MenuItem will handle it via context.onClose
                                },
                                onKeyDown: (e) => {
                                    // Handle keyboard navigation for closing submenu
                                    if (e.key === 'ArrowLeft' || e.key === 'Escape') {
                                        e.preventDefault();
                                        e.stopPropagation();
                                        state.close();
                                        // Return focus to trigger
                                        domTriggerRef.current?.focus();
                                    }
                                    // Call original handler if exists
                                    menu.props.onKeyDown?.(e);
                                },
                                ref: menuRef,
                            }) }), _jsx(DismissButton, { onDismiss: state.close })] }) }))] }));
}
/**
 * Public SubMenuTrigger component that users interact with.
 * It just provides the getCollectionNode for the collection system.
 */
export function SubMenuTrigger(props) {
    // This component is never actually rendered directly.
    // The collection system uses getCollectionNode to build the menu.
    return null;
}
// Allow React Stately collection builder to treat SubMenuTrigger as an Item
SubMenuTrigger.getCollectionNode = function* (props) {
    const [trigger, menu] = React.Children.toArray(props.children);
    // Yield a collection node that tells the Menu to wrap this item with InternalSubMenuTrigger
    yield {
        element: trigger,
        wrapper: (element) => (_jsxs(InternalSubMenuTrigger, { targetKey: element.key || undefined, ...props, children: [element, menu] }, element.key || undefined)),
    };
};
SubMenuTrigger.displayName = 'SubMenuTrigger';

        