// Copyright 1999-2023. Plesk International GmbH. All rights reserved.

import { wrapFunction, safeInvoke, createFocusManager } from '../utils';
import classNames from 'classnames';
import { CLS_PREFIX } from '../../constants';
import MenuItem from './MenuItem';
import MenuSelectableItem from './MenuSelectableItem';
import { Children, cloneElement, isValidElement, forwardRef, useRef, useMemo } from 'react';
import { jsx as _jsx } from "react/jsx-runtime";
const hasIconItem = children => {
  let result = false;
  Children.forEach(children, child => {
    if ( /*#__PURE__*/isValidElement(child) && (child.type === MenuSelectableItem || child.props.icon)) {
      result = true;
    }
  });
  return result;
};
/**
 * `Menu` component displays grouped controls for navigating the UI, performing actions on objects, or showing
 * options for [Lists](#!/List) (for example, sorting and filtering settings). `Menu` is most typically used in a
 * [Dropdown](#!/Dropdown).
 *
 * `Menu` consists of several [Menu Items](#!/MenuItem) (or [Selectable Menu
 * Items](#!/MenuSelectableItem)) which can be grouped by [Menu Headers](#!/MenuHeader)
 * or separated by [Menu Dividers](#!/MenuDivider).
 * @since 0.0.55
 */
const Menu = /*#__PURE__*/forwardRef(function Menu(_ref, ref) {
  let {
    className,
    children,
    onItemClick,
    onKeyDown,
    onFocus,
    autoFocus,
    overlay = false,
    baseClassName = `${CLS_PREFIX}menu`,
    ...props
  } = _ref;
  const rootRef = useRef(null);
  const {
    focusNext,
    focusPrev,
    focusFirst,
    focusLast
  } = useMemo(() => createFocusManager(rootRef, node => (node.getAttribute('role') === 'menuitem' || node.getAttribute('role') === 'menuitemcheckbox') && node.getAttribute('aria-disabled') !== 'true'), []);
  const handleKeyDown = e => {
    switch (e.key) {
      case 'ArrowUp':
        e.preventDefault();
        focusPrev();
        break;
      case 'ArrowDown':
        e.preventDefault();
        focusNext();
        break;
      case 'Home':
      case 'PageUp':
        e.preventDefault();
        focusFirst();
        break;
      case 'End':
      case 'PageDown':
        e.preventDefault();
        focusLast();
        break;
    }
    safeInvoke(onKeyDown, e);
  };
  const handleFocus = e => {
    if (e.target === rootRef.current && autoFocus) {
      focusFirst();
    }
    safeInvoke(onFocus, e);
  };
  let hasTabIndex = false;
  const items = Children.map(children, (child, index) => {
    if (! /*#__PURE__*/isValidElement(child)) {
      return child;
    }
    const props = {
      tabIndex: -1
    };
    if (onItemClick) {
      props.onClick = wrapFunction(child.props.onClick, onItemClick.bind(null, child, index));
    }
    if (!hasTabIndex && (child.type === MenuItem || child.type === MenuSelectableItem) && !child.props.disabled) {
      props.tabIndex = 0;
      hasTabIndex = true;
    } else {
      props.tabIndex = -1;
    }
    return /*#__PURE__*/cloneElement(child, props);
  });
  return /*#__PURE__*/_jsx("div", {
    className: classNames(baseClassName, className, {
      [`${baseClassName}--icons`]: hasIconItem(children),
      [`${baseClassName}--overlay`]: overlay
    }),
    role: "menu",
    ...props,
    ref: el => {
      rootRef.current = el;
      if (ref && typeof ref !== 'function') {
        ref.current = el;
      }
    },
    onKeyDown: handleKeyDown,
    onFocus: handleFocus,
    tabIndex: -1,
    children: items
  });
});
Menu.displayName = 'Menu';
export default Menu;