import _extends from "@babel/runtime/helpers/extends";
// Copyright 1999-2020. Plesk International GmbH. All rights reserved.
import React, { Children, cloneElement, isValidElement, forwardRef, useRef, useMemo } from 'react';
import { wrapFunction, safeInvoke, createFocusManager } from '../utils';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { CLS_PREFIX } from '../../constants';
import MenuItem from './MenuItem';
import MenuSelectableItem from './MenuSelectableItem';

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({
  baseClassName,
  className,
  children,
  onItemClick,
  overlay,
  onKeyDown,
  onFocus,
  autoFocus,
  ...props
}, ref) {
  const rootRef = useRef();
  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__*/React.createElement("div", _extends({
    className: classNames(baseClassName, className, {
      [`${baseClassName}--icons`]: hasIconItem(children),
      [`${baseClassName}--overlay`]: overlay
    }),
    role: "menu"
  }, props, {
    ref: el => {
      rootRef.current = el;

      if (ref) {
        ref.current = el;
      }
    },
    onKeyDown: handleKeyDown,
    onFocus: handleFocus,
    tabIndex: -1
  }), items);
});
Menu.displayName = 'Menu';
Menu.propTypes = {
  /**
   * Triggered when menu item was clicked.
   * @since 0.0.56
   */
  onItemClick: PropTypes.func,

  /**
   * Content of the `Menu`.
   * @since 0.0.55
   */
  children: PropTypes.node,

  /**
   * @ignore
   */
  onKeyDown: PropTypes.func,

  /**
   * @ignore
   */
  onFocus: PropTypes.func,

  /**
   * @ignore
   */
  autoFocus: PropTypes.bool,

  /**
   * Show menu in overlay.
   * @ignore
   */
  overlay: PropTypes.bool,

  /**
   * @ignore
   */
  className: PropTypes.string,

  /**
   * @ignore
   */
  baseClassName: PropTypes.string
};
Menu.defaultProps = {
  onItemClick: null,
  children: null,
  overlay: false,
  className: null,
  baseClassName: `${CLS_PREFIX}menu`,
  onKeyDown: undefined,
  onFocus: undefined,
  autoFocus: undefined
};
export default Menu;