import { useState, useId, useRef, useCallback } from 'react';

const useMenuInteraction = ({
  items,
  sectionsMeta: _sectionsMeta,
  onItemActivate,
  selectedItemIds,
  displayAs: _displayAs,
  closeOnActivate,
  disabled = false,
  id,
  triggerRef,
  label,
  onImplicitClose,
  onExplicitClose
}) => {
  const [isOpen, setIsOpen] = useState(false);
  const [highlightedIndex, setHighlightedIndex] = useState(-1);
  const generatedId = useId();
  const menuId = `${id}-menu-${generatedId}`;
  const menuContainerRef = useRef(null);
  const listRef = useRef(null);
  const isItemDisabled = useCallback(
    (item) => {
      return (disabled || item.disabled) ?? false;
    },
    [disabled]
  );
  const findNextEnabledIndex = useCallback(
    (startIndex, direction, wrap = true) => {
      if (items.length === 0) return -1;
      const len = items.length;
      let index = startIndex;
      for (let i = 0; i < len; i++) {
        index = wrap ? (index + direction + len) % len : Math.min(Math.max(index + direction, 0), len - 1);
        if (!isItemDisabled(items[index])) return index;
        if (!wrap && (index === 0 || index === len - 1)) return -1;
      }
      return -1;
    },
    [items, isItemDisabled]
  );
  const openMenu = useCallback(() => {
    if (disabled) return;
    setIsOpen(true);
  }, [disabled]);
  const closeMenu = useCallback(
    (options) => {
      setIsOpen(false);
      setHighlightedIndex(-1);
      if (options?.restoreFocus !== false) {
        triggerRef.current?.focus();
        onExplicitClose?.();
      } else {
        onImplicitClose?.();
      }
    },
    [triggerRef, onImplicitClose, onExplicitClose]
  );
  const getItemId = useCallback(
    (index) => `${menuId}-option-${index}`,
    [menuId]
  );
  const handleKeyDown = useCallback(
    (e) => {
      if (!isOpen) return;
      switch (e.key) {
        case "ArrowDown": {
          e.preventDefault();
          const next = highlightedIndex < 0 ? findNextEnabledIndex(-1, 1) : findNextEnabledIndex(highlightedIndex, 1);
          if (next >= 0) {
            setHighlightedIndex(next);
            listRef.current?.scrollToIndex(next);
          }
          break;
        }
        case "ArrowUp": {
          e.preventDefault();
          const prev = highlightedIndex < 0 ? findNextEnabledIndex(items.length, -1) : findNextEnabledIndex(highlightedIndex, -1);
          if (prev >= 0) {
            setHighlightedIndex(prev);
            listRef.current?.scrollToIndex(prev);
          }
          break;
        }
        case "Home": {
          e.preventDefault();
          const first = findNextEnabledIndex(-1, 1, false);
          if (first >= 0) {
            setHighlightedIndex(first);
            listRef.current?.scrollToIndex(first);
          }
          break;
        }
        case "End": {
          e.preventDefault();
          const last = findNextEnabledIndex(items.length, -1, false);
          if (last >= 0) {
            setHighlightedIndex(last);
            listRef.current?.scrollToIndex(last);
          }
          break;
        }
        case "Enter": {
          e.preventDefault();
          if (highlightedIndex >= 0 && highlightedIndex < items.length) {
            const item = items[highlightedIndex];
            if (!isItemDisabled(item)) {
              onItemActivate(item);
              if (closeOnActivate) {
                closeMenu();
              }
            }
          }
          break;
        }
        case " ": {
          const target = e.target;
          if (target.tagName === "INPUT") break;
          e.preventDefault();
          if (highlightedIndex >= 0 && highlightedIndex < items.length) {
            const item = items[highlightedIndex];
            if (!isItemDisabled(item)) {
              onItemActivate(item);
              if (closeOnActivate) {
                closeMenu();
              }
            }
          }
          break;
        }
        case "Escape": {
          e.preventDefault();
          closeMenu();
          break;
        }
        case "Tab": {
          closeMenu({ restoreFocus: false });
          break;
        }
      }
    },
    [
      isOpen,
      highlightedIndex,
      items,
      findNextEnabledIndex,
      isItemDisabled,
      onItemActivate,
      closeOnActivate,
      closeMenu
    ]
  );
  const handleTriggerKeyDown = useCallback(
    (e) => {
      if (e.key === "ArrowDown" || e.key === "ArrowUp") {
        e.preventDefault();
        if (!isOpen) openMenu();
      }
      if (e.key === "Enter" || e.key === " ") {
        e.preventDefault();
        if (isOpen) {
          closeMenu();
        } else {
          openMenu();
        }
      }
    },
    [isOpen, openMenu, closeMenu]
  );
  const getTriggerProps = useCallback(() => {
    return {
      ref: triggerRef,
      onClick: () => {
        if (isOpen) {
          closeMenu();
        } else {
          openMenu();
        }
      },
      onKeyDown: handleTriggerKeyDown,
      "aria-haspopup": "listbox",
      "aria-controls": menuId,
      "aria-expanded": isOpen,
      "data-state": isOpen ? "open" : "close"
    };
  }, [isOpen, openMenu, closeMenu, menuId, handleTriggerKeyDown, triggerRef]);
  const getMenuProps = useCallback(
    (opts) => {
      return {
        role: "listbox",
        id: menuId,
        "aria-label": label,
        tabIndex: 0,
        "aria-activedescendant": highlightedIndex >= 0 ? getItemId(highlightedIndex) : void 0,
        ref: menuContainerRef,
        onKeyDown: handleKeyDown,
        className: opts?.className,
        style: { outline: "none", ...opts?.style }
      };
    },
    [menuId, label, highlightedIndex, getItemId, handleKeyDown]
  );
  const getItemProps = useCallback(
    (opts) => {
      const { item, index, className, "data-type": dataType } = opts;
      return {
        role: "option",
        id: getItemId(index),
        "aria-selected": selectedItemIds.has(item.original.id),
        "aria-disabled": isItemDisabled(item) || void 0,
        onClick: () => {
          if (isItemDisabled(item)) return;
          onItemActivate(item);
          if (closeOnActivate) {
            closeMenu();
          }
        },
        onMouseMove: () => {
          if (highlightedIndex !== index) {
            setHighlightedIndex(index);
          }
        },
        className,
        "data-type": dataType
      };
    },
    [
      getItemId,
      selectedItemIds,
      isItemDisabled,
      onItemActivate,
      closeOnActivate,
      closeMenu,
      highlightedIndex
    ]
  );
  return {
    isOpen,
    openMenu,
    closeMenu,
    highlightedIndex,
    setHighlightedIndex,
    getTriggerProps,
    getMenuProps,
    getItemProps,
    listRef,
    menuContainerRef,
    handleKeyDown
  };
};

export { useMenuInteraction as u };
//# sourceMappingURL=useMenuInteraction-BwZ2ORo9.js.map
