import { useEffect, useRef } from "preact/compat";
import { DropdownMenuOption } from "./DropdownMenuOption";
import { DropdownMenuSection } from "./DropdownMenuSection";
// from react-stately
import { useListBox } from "../react-aria"; // from react-aria
import usePressEscapeHandler from "../utilities/usePressEscapeHandler";
import classNames from 'classnames';
import { jsx as _jsx, jsxs as _jsxs } from "preact/compat/jsx-runtime";
export function DropdownMenu(_ref) {
  let {
    children,
    componentClass,
    heading,
    labelId,
    menuId,
    rootId,
    size,
    state,
    ...props
  } = _ref;
  const fallbackListBoxRef = useRef(null);
  const listBoxRef = props.listBoxRef ?? fallbackListBoxRef;
  const {
    listBoxProps
  } = useListBox(props, state, listBoxRef);
  const headingId = `${rootId}__heading`;
  const containerClass = classNames(`${componentClass}__menu-container`, size && `ds-c-field--${size}`);
  const containerRef = useRef();
  usePressEscapeHandler(containerRef, () => {
    state.setOpen(false);
    props.triggerRef.current?.focus?.();
  });

  // Workaround for react/react-aria #1513
  useEffect(() => {
    const listener = event => {
      event.preventDefault();
    };
    containerRef.current?.addEventListener('touchend', listener, {
      passive: false
    });
    return () => {
      containerRef.current?.removeEventListener('touchend', listener);
    };
  }, []);
  function handleTabKey(event) {
    const TAB_KEY = 9;
    if (event.keyCode === TAB_KEY || event.key === 'Tab') {
      if (!state.selectionManager.selectedKeys.has(state.selectionManager.focusedKey)) {
        state.selectionManager.setSelectedKeys([state.selectionManager.focusedKey]);
      }
    }
  }
  const sharedProps = {
    state,
    rootId,
    componentClass
  };

  // These must be mutually exclusive, because when we force the menu to render open when
  // react-aria's state doesn't consider it open (state.isOpen), it seems to actually
  // render unexpected items. Currently we don't have a reason to render both at the same
  // time, so this is fine.
  const contents = children ?? [...state.collection].map(item => item.type === 'section' ? /*#__PURE__*/_jsx(DropdownMenuSection, {
    section: item,
    ...sharedProps
  }, item.key) : /*#__PURE__*/_jsx(DropdownMenuOption, {
    item: item,
    ...sharedProps
  }, item.key));
  return /*#__PURE__*/_jsxs("div", {
    className: containerClass,
    ref: containerRef,
    onKeyDown: handleTabKey,
    children: [heading && /*#__PURE__*/_jsx("h5", {
      className: "ds-c-autocomplete__label",
      id: headingId,
      children: heading
    }), /*#__PURE__*/_jsx("ul", {
      ...listBoxProps,
      id: menuId,
      "aria-labelledby": classNames(labelId, heading && headingId),
      className: `${componentClass}__menu`,
      ref: listBoxRef,
      children: contents
    })]
  });
}
export default DropdownMenu;