import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
import React, { useCallback, useContext, useMemo } from 'react';
import PropTypes from 'prop-types';
import omit from 'lodash/omit';
import DropdownMenu from './DropdownMenu';
import { mergeRefs, PLACEMENT_8, placementPolyfill, useClassNames } from '../utils';
import { SidenavContext } from '../Sidenav/Sidenav';
import deprecatePropType from '../utils/deprecatePropType';
import DropdownItem from './DropdownItem';
import DropdownContext from './DropdownContext';
import Menu from '../Menu/Menu';
import DropdownToggle from './DropdownToggle';
import MenuContext from '../Menu/MenuContext';
import MenuItem from '../Menu/MenuItem';
import kebabCase from 'lodash/kebabCase';
import { NavbarContext } from '../Navbar/Navbar';
import Disclosure from '../Disclosure/Disclosure';
import SidenavDropdown from '../Sidenav/SidenavDropdown';
import NavContext from '../Nav/NavContext';
var defaultProps = {
  as: 'div',
  classPrefix: 'dropdown',
  placement: 'bottomStart',
  trigger: 'click'
};
/**
 * The <Dropdown> API
 * When used inside <Sidenav>, renders a <TreeviewRootItem>;
 * Otherwise renders a <MenuRoot>
 */

var Dropdown = /*#__PURE__*/React.forwardRef(function (props, ref) {
  var activeKey = props.activeKey,
      onSelectProp = props.onSelect,
      rest = _objectWithoutPropertiesLoose(props, ["activeKey", "onSelect"]);

  var Component = rest.as,
      title = rest.title,
      onClose = rest.onClose,
      onOpen = rest.onOpen,
      onToggle = rest.onToggle,
      eventKey = rest.eventKey,
      trigger = rest.trigger,
      placement = rest.placement,
      renderTitle = rest.renderTitle,
      toggleAs = rest.toggleAs,
      toggleClassName = rest.toggleClassName,
      classPrefix = rest.classPrefix,
      className = rest.className,
      disabled = rest.disabled,
      children = rest.children,
      menuStyle = rest.menuStyle,
      style = rest.style,
      menuProps = _objectWithoutPropertiesLoose(rest, ["as", "title", "onClose", "onOpen", "onToggle", "eventKey", "trigger", "placement", "renderTitle", "toggleAs", "toggleClassName", "classPrefix", "className", "disabled", "children", "menuStyle", "style"]);

  var _useContext = useContext(NavContext),
      onSelectFromNav = _useContext.onSelect;

  var emitSelect = useCallback(function (eventKey, event) {
    onSelectProp === null || onSelectProp === void 0 ? void 0 : onSelectProp(eventKey, event); // If <Dropdown> is inside <Nav>, also trigger `onSelect` on <Nav>

    onSelectFromNav === null || onSelectFromNav === void 0 ? void 0 : onSelectFromNav(eventKey, event);
  }, [onSelectProp, onSelectFromNav]);

  var _useClassNames = useClassNames(classPrefix),
      merge = _useClassNames.merge,
      withClassPrefix = _useClassNames.withClassPrefix,
      prefix = _useClassNames.prefix;

  var _useClassNames2 = useClassNames('dropdown-menu'),
      withMenuClassPrefix = _useClassNames2.withClassPrefix,
      mergeMenuClassName = _useClassNames2.merge;

  var _useClassNames3 = useClassNames('nav-item'),
      withNavItemClassPrefix = _useClassNames3.withClassPrefix,
      mergeNavItemClassNames = _useClassNames3.merge;

  var menuButtonTriggers = useMemo(function () {
    if (!trigger) {
      return undefined;
    }

    var triggerMap = {
      hover: 'mouseover',
      click: 'click',
      contextMenu: 'contextmenu'
    };

    if (!Array.isArray(trigger)) {
      return [triggerMap[trigger]];
    }

    return trigger.map(function (t) {
      return triggerMap[t];
    });
  }, [trigger]);
  var parentMenu = useContext(MenuContext);
  var sidenav = useContext(SidenavContext);
  var navbar = useContext(NavbarContext); // Render a disclosure when inside expanded <Sidenav>

  if (sidenav !== null && sidenav !== void 0 && sidenav.expanded) {
    return /*#__PURE__*/React.createElement(DropdownContext.Provider, {
      value: {
        activeKey: activeKey,
        onSelect: emitSelect
      }
    }, /*#__PURE__*/React.createElement(SidenavDropdown, _extends({
      ref: ref
    }, rest)));
  } // Renders a disclosure when used inside <Navbar>


  if (navbar) {
    return /*#__PURE__*/React.createElement(DropdownContext.Provider, {
      value: {
        activeKey: activeKey,
        onSelect: emitSelect
      }
    }, /*#__PURE__*/React.createElement(Disclosure, {
      hideOnClickOutside: true
    }, function (_ref, containerRef) {
      var _withClassPrefix;

      var open = _ref.open;
      var classes = merge(className, withClassPrefix((_withClassPrefix = {}, _withClassPrefix["placement-" + kebabCase(placementPolyfill(placement))] = !!placement, _withClassPrefix.disabled = disabled, _withClassPrefix.open = open, _withClassPrefix)));
      return /*#__PURE__*/React.createElement(Component, {
        ref: mergeRefs(ref, containerRef),
        className: classes,
        style: style
      }, /*#__PURE__*/React.createElement(Disclosure.Button, null, function (buttonProps, buttonRef) {
        return /*#__PURE__*/React.createElement(DropdownToggle, _extends({
          ref: buttonRef,
          as: renderTitle ? 'span' : toggleAs,
          className: toggleClassName,
          placement: placement,
          disabled: disabled
        }, omit(buttonProps, ['open']), menuProps), title);
      }), /*#__PURE__*/React.createElement(Disclosure.Content, null, function (_ref2, elementRef) {
        var open = _ref2.open;
        var menuClassName = mergeMenuClassName(className, withMenuClassPrefix());
        return /*#__PURE__*/React.createElement("ul", {
          ref: elementRef,
          className: menuClassName,
          style: menuStyle,
          hidden: !open
        }, children);
      }));
    }));
  }

  var renderMenuButton = function renderMenuButton(menuButtonProps, menuButtonRef) {
    return /*#__PURE__*/React.createElement(DropdownToggle, _extends({
      ref: menuButtonRef,
      as: renderTitle ? 'span' : toggleAs,
      className: toggleClassName,
      placement: placement,
      disabled: disabled
    }, omit(menuButtonProps, ['open']), menuProps), title);
  };

  if (parentMenu) {
    renderMenuButton = function renderMenuButton(menuButtonProps, buttonRef) {
      return /*#__PURE__*/React.createElement(MenuItem, {
        disabled: disabled
      }, function (_ref3, menuitemRef) {
        var active = _ref3.active,
            menuitemProps = _objectWithoutPropertiesLoose(_ref3, ["active"]);

        return /*#__PURE__*/React.createElement(DropdownToggle, _extends({
          ref: mergeRefs(buttonRef, menuitemRef),
          as: renderTitle ? 'span' : toggleAs,
          className: mergeNavItemClassNames(toggleClassName, withNavItemClassPrefix({
            focus: active
          }))
        }, menuButtonProps, omit(menuitemProps, ['onClick']), menuProps), title);
      });
    };
  }

  return /*#__PURE__*/React.createElement(DropdownContext.Provider, {
    value: {
      activeKey: activeKey,
      onSelect: emitSelect
    }
  }, /*#__PURE__*/React.createElement(Menu, {
    menuButtonText: title,
    renderMenuButton: renderMenuButton,
    openMenuOn: menuButtonTriggers,
    renderMenuPopup: function renderMenuPopup(_ref4, popupRef) {
      var open = _ref4.open,
          popupProps = _objectWithoutPropertiesLoose(_ref4, ["open"]);

      var menuClassName = mergeMenuClassName(className, withMenuClassPrefix()); // When inside a collapsed <Sidenav>, render a header in menu

      var showHeader = !!sidenav;
      return /*#__PURE__*/React.createElement("ul", _extends({
        ref: popupRef,
        className: menuClassName,
        style: menuStyle,
        hidden: !open
      }, popupProps), showHeader && /*#__PURE__*/React.createElement("div", {
        className: prefix('header')
      }, title), children);
    },
    onToggleMenu: function onToggleMenu(open, event) {
      onToggle === null || onToggle === void 0 ? void 0 : onToggle(open);
      sidenav === null || sidenav === void 0 ? void 0 : sidenav.onOpenChange(eventKey, event);

      if (open) {
        onOpen === null || onOpen === void 0 ? void 0 : onOpen();
      } else {
        onClose === null || onClose === void 0 ? void 0 : onClose();
      }
    }
  }, function (_ref5, menuContainerRef) {
    var _withClassPrefix2;

    var open = _ref5.open,
        menuContainer = _objectWithoutPropertiesLoose(_ref5, ["open"]);

    var classes = merge(className, withClassPrefix((_withClassPrefix2 = {}, _withClassPrefix2["placement-" + kebabCase(placementPolyfill(placement))] = !!placement, _withClassPrefix2.disabled = disabled, _withClassPrefix2.open = open, _withClassPrefix2.submenu = !!parentMenu, _withClassPrefix2)));
    return /*#__PURE__*/React.createElement(Component, _extends({
      ref: mergeRefs(ref, menuContainerRef),
      className: classes
    }, menuContainer, {
      style: style
    }));
  }));
});
Dropdown.Item = DropdownItem;
Dropdown.Menu = DropdownMenu;
Dropdown.displayName = 'Dropdown';
Dropdown.defaultProps = defaultProps;
Dropdown.propTypes = {
  activeKey: PropTypes.any,
  classPrefix: PropTypes.string,
  trigger: PropTypes.oneOfType([PropTypes.array, PropTypes.oneOf(['click', 'hover', 'contextMenu'])]),
  placement: PropTypes.oneOf(PLACEMENT_8),
  title: PropTypes.node,
  disabled: PropTypes.bool,
  icon: PropTypes.node,
  menuStyle: PropTypes.object,
  className: PropTypes.string,
  toggleClassName: PropTypes.string,
  children: PropTypes.node,
  open: deprecatePropType(PropTypes.bool),
  eventKey: PropTypes.any,
  as: PropTypes.elementType,
  toggleAs: PropTypes.elementType,
  noCaret: PropTypes.bool,
  style: PropTypes.object,
  onClose: PropTypes.func,
  onOpen: PropTypes.func,
  onToggle: PropTypes.func,
  onSelect: PropTypes.func,
  onMouseEnter: PropTypes.func,
  onMouseLeave: PropTypes.func,
  onContextMenu: PropTypes.func,
  onClick: PropTypes.func,
  renderTitle: PropTypes.func
};
export default Dropdown;