import _extends from "@babel/runtime/helpers/extends";
// Copyright 1999-2020. Plesk International GmbH. All rights reserved.
import { isRtl } from '../../utils';
import React, { cloneElement, isValidElement, useState, useEffect, useRef } from 'react';
import { wrapFunction } from '../utils';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { CLS_PREFIX, Z_INDEX_DROPDOWN, Z_INDEX_OVERLAY } from '../../constants';
import Button from '../Button';
import AutoClosable from '../AutoClosable';
import Popper from '../Popper';
import Layer from '../Layer';
import { MenuItem, MenuDivider } from '../Menu';
import Translate from '../Translate';
import localeFallback from './locale/en-US';

const createTarget = (node, {
  onToggle,
  targetRef
}) => {
  if (false === ( /*#__PURE__*/isValidElement(node) && node.type !== Translate)) {
    node = /*#__PURE__*/React.createElement(Button, {
      caret: true
    }, node);
  }

  let isKeyboardEvent = false;
  return /*#__PURE__*/cloneElement(node, {
    onKeyDown: wrapFunction(node.props.onKeyDown, e => {
      isKeyboardEvent = e.key === ' ' || e.key === 'Enter';
    }),
    onClick: wrapFunction(node.props.onClick, e => {
      targetRef.current = e.currentTarget;
      onToggle(isKeyboardEvent);
      isKeyboardEvent = false;
    }),
    'aria-haspopup': true
  });
};

const computePlacement = placement => {
  const [side, align] = placement.split('-');

  if (align && isRtl() && ['top', 'bottom'].indexOf(side) !== -1) {
    return "".concat(side, "-").concat(align === 'start' ? 'end' : 'start');
  }

  return placement;
};

const useEnhancedMenu = (menu, {
  baseClassName,
  onClose,
  overlay,
  locale,
  autoFocus
}) => {
  const menuRef = useRef();
  const triggerRef = useRef();
  useEffect(() => {
    if (menuRef.current && !overlay) {
      triggerRef.current = document.activeElement;
      setTimeout(() => {
        if (menuRef.current) {
          menuRef.current.focus();
        }
      });
    }
  });

  const handleClose = () => {
    if (triggerRef.current) {
      triggerRef.current.focus();
    }

    onClose();
  };

  const handleKeyDown = e => {
    e.stopPropagation();

    switch (e.key) {
      case 'Enter':
        e.preventDefault();
        document.activeElement.click();
        break;

      case 'Escape':
        e.preventDefault();
        handleClose();
        break;

      case 'Tab':
        handleClose();
        break;
    }
  };

  let {
    children
  } = menu.props;

  if (overlay) {
    children = [...menu.props.children, /*#__PURE__*/React.createElement(MenuDivider, {
      className: "".concat(baseClassName, "__overlay-menu-divider"),
      key: "divider"
    }), /*#__PURE__*/React.createElement(MenuItem, {
      onClick: handleClose,
      key: "close"
    }, /*#__PURE__*/React.createElement(Translate, {
      namespace: "Dropdown",
      content: "close",
      translators: locale,
      fallback: localeFallback.close
    }))];
  }

  const clone = /*#__PURE__*/cloneElement(menu, {
    onItemClick: wrapFunction(menu.props.onItemClick, handleClose),
    className: classNames("".concat(baseClassName, "__menu"), menu.props.className),
    overlay,
    ref: menuRef,
    children,
    onKeyDown: handleKeyDown,
    autoFocus
  });
  return {
    enhancedMenu: clone,
    menuRef
  };
};
/**
 * `Dropdown` component is a [Button](#!/Button) that opens a drop-down (nested) [Menu](#!/Menu).
 * Use dropdown for grouping actions that are not used often or are less important than others -- in other words,
 * for stuff that you don't want to show users all the time, especially if you have limited screen space.
 * @since 0.0.57
 */


const Dropdown = ({
  baseClassName,
  className,
  children,
  menu,
  menuPlacement,
  overlay,
  locale,
  ...props
}) => {
  const [opened, setOpened] = useState(false);
  const [autoFocus, setAutoFocus] = useState(false);
  const closeTimerRef = useRef();
  useEffect(() => {
    return () => {
      clearTimeout(closeTimerRef.current);
    };
  }, []);

  const handleOpen = isKeyboardEvent => {
    setAutoFocus(isKeyboardEvent);
    setOpened(true);
  };

  const handleClose = () => {
    closeTimerRef.current = setTimeout(() => {
      setOpened(false);
    }, 0);
  };

  const {
    enhancedMenu,
    menuRef
  } = useEnhancedMenu(menu, {
    baseClassName,
    onClose: handleClose,
    overlay,
    locale,
    autoFocus
  });
  const targetRef = useRef();
  const target = createTarget(children, {
    onToggle: handleOpen,
    targetRef
  });
  return /*#__PURE__*/React.createElement("div", _extends({
    className: classNames(baseClassName, {
      ["".concat(baseClassName, "--opened")]: opened
    }, className)
  }, props), overlay ? /*#__PURE__*/React.createElement(React.Fragment, null, target, opened && /*#__PURE__*/React.createElement(Layer, {
    level: Z_INDEX_OVERLAY
  }, /*#__PURE__*/React.createElement("div", {
    className: "".concat(baseClassName, "__overlay")
  }, /*#__PURE__*/React.createElement(AutoClosable, {
    onClose: handleClose,
    nodeRef: menuRef
  }, /*#__PURE__*/React.createElement("div", {
    className: "".concat(baseClassName, "__overlay-menu")
  }, enhancedMenu))))) : /*#__PURE__*/React.createElement(Popper, {
    target: target,
    targetRef: targetRef,
    placement: computePlacement(menuPlacement),
    show: opened,
    className: "".concat(baseClassName, "__popper"),
    zIndex: Z_INDEX_DROPDOWN
  }, /*#__PURE__*/React.createElement(AutoClosable, {
    onClose: handleClose,
    nodeRef: menuRef
  }, enhancedMenu)));
};

Dropdown.propTypes = {
  /**
   * Dropdown [menu](#!/Menu).
   * @since 0.0.57
   */
  menu: PropTypes.element.isRequired,

  /**
   * Menu placement.
   * @since 0.0.60
   */
  menuPlacement: PropTypes.string,

  /**
   * Content of the `Dropdown`.
   * @since 0.0.57
   */
  children: PropTypes.node,

  /**
   * Custom localization messages.
   * @since 3.6.0
   */
  locale: PropTypes.shape({
    close: PropTypes.node
  }),

  /**
   * Display menu as overlay.
   * @ignore
   */
  overlay: PropTypes.bool,

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

  /**
   * @ignore
   */
  baseClassName: PropTypes.string
};
Dropdown.defaultProps = {
  menuPlacement: 'bottom-start',
  children: undefined,
  overlay: false,
  className: undefined,
  baseClassName: "".concat(CLS_PREFIX, "dropdown"),
  locale: undefined
};
export default Dropdown;