/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-af8d194 | Cube Dev Team */
import { useEventBus } from "../../../utils/react/useEventBus.js";
import { MenuContext, useMenuContext } from "./context.js";
import { SubmenuTriggerContext } from "./SubmenuTriggerContext.js";
import { generateRandomId } from "../../../utils/random.js";
import { _Popover } from "../../overlays/Modal/Popover.js";
import React, { useEffect, useMemo, useRef } from "react";
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
import { DismissButton, useMenuTrigger, useOverlayPosition } from "react-aria";
import { useMenuTriggerState } from "react-stately";
import { useSyncRef } from "@react-aria/utils";

//#region src/components/actions/Menu/SubMenuTrigger.tsx
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;
	const [menuTrigger, menu] = React.Children.toArray(children);
	const state = useMenuTriggerState(props);
	const submenuId = useMemo(() => generateRandomId(), []);
	const { emit, on } = useEventBus();
	const domTriggerRef = useRef(null);
	const popoverRef = useRef(null);
	const menuRef = useRef(null);
	const { menuTriggerProps: rawTriggerProps, menuProps } = useMenuTrigger({
		type: "submenu",
		isDisabled
	}, state, domTriggerRef);
	const parentContext = useMenuContext();
	const { onKeyDown: _mtOnKeyDown, onPress: _mtOnPress, onPressStart: _mtOnPressStart, onKeyUp: _mtOnKeyUp, ...menuTriggerProps } = rawTriggerProps;
	const { overlayProps: positionProps } = useOverlayPosition({
		targetRef: domTriggerRef,
		overlayRef: popoverRef,
		scrollRef: menuRef,
		placement,
		offset,
		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(() => {
		return {
			...menuProps,
			ref: menuRef,
			onClose: () => {
				state.close();
				if (parentContext.onClose) parentContext.onClose();
			},
			closeOnSelect: true,
			autoFocus,
			mods: { popover: true },
			isClosing: parentContext.isClosing || !state.isOpen
		};
	}, [
		menuProps,
		autoFocus,
		state,
		parentContext.onClose,
		parentContext.isClosing
	]);
	useSyncRef(parentContext, domTriggerRef);
	useEffect(() => {
		return on("popover:open", (data) => {
			if (data.menuId !== submenuId && state.isOpen) state.close();
		});
	}, [
		on,
		submenuId,
		state
	]);
	useEffect(() => {
		if (state.isOpen) emit("popover:open", { menuId: submenuId });
	}, [
		state.isOpen,
		emit,
		submenuId
	]);
	useEffect(() => {
		return () => {
			if (hoverOpenTimerRef.current) clearTimeout(hoverOpenTimerRef.current);
			if (hoverCloseTimerRef.current) clearTimeout(hoverCloseTimerRef.current);
			isHoveringRef.current = false;
			isHoveringSubmenuRef.current = false;
		};
	}, []);
	const handleKeyDown = (e) => {
		if (isDisabled) return;
		if (e.key === "ArrowRight") {
			e.preventDefault();
			e.stopPropagation();
			state.open();
		} else if (e.key === "Enter" || e.key === " ") {
			e.preventDefault();
			e.stopPropagation();
			e.nativeEvent.stopImmediatePropagation();
			state.open();
			suppressNextActionRef.current = true;
		} else if (e.key === "ArrowLeft" && state.isOpen) {
			e.preventDefault();
			e.stopPropagation();
			state.close();
		}
	};
	const hoverOpenTimerRef = useRef(null);
	const hoverCloseTimerRef = useRef(null);
	const isHoveringRef = useRef(false);
	const isHoveringSubmenuRef = useRef(false);
	const suppressNextActionRef = useRef(false);
	const checkShouldClose = () => {
		if (!isHoveringRef.current && !isHoveringSubmenuRef.current) hoverCloseTimerRef.current = setTimeout(() => {
			if (!isHoveringRef.current && !isHoveringSubmenuRef.current) state.close();
		}, 300);
	};
	const handleMouseEnter = () => {
		if (isDisabled) return;
		isHoveringRef.current = true;
		if (hoverCloseTimerRef.current) {
			clearTimeout(hoverCloseTimerRef.current);
			hoverCloseTimerRef.current = null;
		}
		if (!state.isOpen) hoverOpenTimerRef.current = setTimeout(() => {
			if (isHoveringRef.current) state.open();
		}, 200);
	};
	const handleMouseLeave = () => {
		isHoveringRef.current = false;
		if (hoverOpenTimerRef.current) {
			clearTimeout(hoverOpenTimerRef.current);
			hoverOpenTimerRef.current = null;
		}
		checkShouldClose();
	};
	const handlePopoverMouseEnter = () => {
		isHoveringSubmenuRef.current = true;
		if (hoverCloseTimerRef.current) {
			clearTimeout(hoverCloseTimerRef.current);
			hoverCloseTimerRef.current = null;
		}
	};
	const handlePopoverMouseLeave = () => {
		isHoveringSubmenuRef.current = false;
		checkShouldClose();
	};
	const triggerContextValue = useMemo(() => ({
		triggerRef: domTriggerRef,
		triggerProps: menuTriggerProps,
		isOpen: state.isOpen,
		isDisabled,
		onMouseEnter: handleMouseEnter,
		onMouseLeave: handleMouseLeave,
		onKeyDown: handleKeyDown,
		onAction: isDisabled ? void 0 : () => {
			if (suppressNextActionRef.current) {
				suppressNextActionRef.current = false;
				return;
			}
			state.open();
		}
	}), [
		state,
		isDisabled,
		handleMouseEnter,
		handleMouseLeave,
		handleKeyDown,
		menuTriggerProps
	]);
	return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(SubmenuTriggerContext.Provider, {
		value: triggerContextValue,
		children: menuTrigger
	}), state.isOpen && /* @__PURE__ */ jsx(_Popover, {
		ref: popoverRef,
		hideArrow: true,
		isNonModal: true,
		isOpen: !parentContext.isClosing,
		style: positionProps.style,
		placement,
		onClose: state.close,
		...overlayProps,
		children: /* @__PURE__ */ jsxs("div", {
			style: { display: "contents" },
			onMouseEnter: handlePopoverMouseEnter,
			onMouseLeave: handlePopoverMouseLeave,
			children: [
				/* @__PURE__ */ jsx(DismissButton, { onDismiss: state.close }),
				/* @__PURE__ */ jsx(MenuContext.Provider, {
					value: nestedMenuContext,
					children: React.cloneElement(menu, {
						...menu.props,
						autoFocus,
						onAction: (key) => {
							menu.props.onAction?.(key);
							onAction?.(key);
						},
						onKeyDown: (e) => {
							if (e.key === "ArrowLeft" || e.key === "Escape") {
								e.preventDefault();
								e.stopPropagation();
								state.close();
								domTriggerRef.current?.focus();
							}
							menu.props.onKeyDown?.(e);
						},
						ref: menuRef
					})
				}),
				/* @__PURE__ */ jsx(DismissButton, { onDismiss: state.close })
			]
		})
	})] });
}
/**
* Public SubMenuTrigger component that users interact with.
* It just provides the getCollectionNode for the collection system.
*/
function SubMenuTrigger(props) {
	return null;
}
SubMenuTrigger.getCollectionNode = function* (props) {
	const [trigger, menu] = React.Children.toArray(props.children);
	yield {
		element: trigger,
		wrapper: (element) => /* @__PURE__ */ jsxs(InternalSubMenuTrigger, {
			targetKey: element.key || void 0,
			...props,
			children: [element, menu]
		}, element.key || void 0)
	};
};
SubMenuTrigger.displayName = "SubMenuTrigger";

//#endregion
export { SubMenuTrigger };
//# sourceMappingURL=SubMenuTrigger.js.map