function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

import React, { Children, cloneElement, forwardRef, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
import clsx from 'clsx';
import { isDef } from '../utils';
import useEventListener from '../hooks/use-event-listener';
import useScrollParent from '../hooks/use-scroll-parent';
import { getRect } from '../hooks/use-rect';
import useRefs from '../hooks/use-refs';
import DropdownMenuContext from './DropdownMenuContext';
import { useUpdateEffect } from '../hooks';
import useClickAway from '../hooks/use-click-away';
import ConfigProviderContext from '../config-provider/ConfigProviderContext';
import useMergedState from '../hooks/use-merged-state';
var DropdownMenu = /*#__PURE__*/forwardRef(function (props, ref) {
  var _useContext = useContext(ConfigProviderContext),
      prefixCls = _useContext.prefixCls,
      createNamespace = _useContext.createNamespace;

  var _createNamespace = createNamespace('dropdown-menu', prefixCls),
      bem = _createNamespace[0];

  var _useMergedState = useMergedState({
    value: props.value,
    defaultValue: props.defaultValue
  }),
      _useMergedState$ = _useMergedState[0],
      innerValue = _useMergedState$ === void 0 ? {} : _useMergedState$,
      setInnerValue = _useMergedState[1];

  var _useRefs = useRefs(),
      childrenRefs = _useRefs[0],
      setChildrenRefs = _useRefs[1];

  var _useState = useState(null),
      showPopupIndex = _useState[0],
      setShowPopupIndex = _useState[1];

  var showPopupIndexRef = useRef();
  var root = useRef();
  var barRef = useRef();
  var offset = useRef(0);
  var isToggleEvent = useRef(false);
  var rect = useRef({
    bottom: 0,
    top: 0
  });
  var innerEffect = useRef(false);
  var opened = useMemo(function () {
    return showPopupIndex !== null;
  }, [showPopupIndex]);

  var barStyle = function barStyle() {
    if (opened && isDef(props.zIndex)) {
      return {
        zIndex: +props.zIndex + 1
      };
    }

    return {};
  };

  var updateShowPopupIndex = function updateShowPopupIndex(current) {
    showPopupIndexRef.current = current;
    setShowPopupIndex(current);
  };

  var closeAll = function closeAll() {
    childrenRefs.forEach(function (item) {
      item.toggle(false);
    });
    updateShowPopupIndex(null);
  };

  var onClickAway = function onClickAway() {
    if (props.closeOnClickOutside && !isToggleEvent.current) {
      closeAll();
    } else {
      isToggleEvent.current = false;
    }
  };

  var updateOffset = function updateOffset() {
    if (barRef.current) {
      rect.current = getRect(barRef.current);

      if (props.direction === 'down') {
        offset.current = rect.current.bottom;
      } else {
        offset.current = window.innerHeight - rect.current.top;
      }
    }
  };

  var onScroll = function onScroll() {
    if (opened) {
      updateOffset();
    }
  };

  var showItem = function showItem(index) {
    var item = childrenRefs[index];
    isToggleEvent.current = true;
    updateOffset();
    updateShowPopupIndex(index);
    item.toggle(true);
  };

  var toggleItem = function toggleItem(active) {
    childrenRefs.forEach(function (item, index) {
      if (index === active) {
        if (active === showPopupIndexRef.current) {
          updateShowPopupIndex(null);
          item.toggle();
          return;
        }

        showItem(active);
      }
    });
  };

  var close = function close() {
    updateShowPopupIndex(null);
  };

  var renderTitle = function renderTitle(item, index) {
    var showPopup = showPopupIndex === index;
    var titleClass = item.titleClass;
    var disabled = props.disabled || item.disabled;
    return /*#__PURE__*/React.createElement("div", {
      key: index,
      role: "button",
      tabIndex: disabled ? -1 : 0,
      className: clsx(bem('item', {
        disabled: disabled
      })),
      onClick: function onClick() {
        if (!disabled) {
          toggleItem(index);
        }
      }
    }, /*#__PURE__*/React.createElement("span", {
      className: clsx(bem('title', {
        down: showPopup === (props.direction === 'down'),
        active: showPopup
      }), titleClass),
      style: {
        color: showPopup ? props.activeColor : ''
      }
    }, /*#__PURE__*/React.createElement("div", {
      className: "rv-ellipsis"
    }, item.renderTitle(innerValue[item.name]))));
  };

  useUpdateEffect(function () {
    if (innerEffect.current) {
      innerEffect.current = false;
      return;
    }

    if (!props.value) {
      setInnerValue(undefined);
      return;
    }

    setInnerValue(props.value);
  }, [props.value]);
  useEffect(function () {
    if (barRef.current) {
      updateOffset();
    }
  }, [barRef.current]);

  var onInnerChange = function onInnerChange(v) {
    innerEffect.current = true;

    var newValue = _extends({}, innerValue, v);

    setInnerValue(newValue);
    if (props.onChange) props.onChange(newValue);
  };

  var scrollParent = useScrollParent(root);
  useEventListener('scroll', onScroll, {
    target: scrollParent
  });
  useClickAway(root, onClickAway);
  useImperativeHandle(ref, function () {
    return {
      toggleItem: toggleItem,
      showItem: showItem,
      close: closeAll
    };
  });
  return /*#__PURE__*/React.createElement(DropdownMenuContext.Provider, {
    value: {
      props: props,
      value: innerValue,
      onChange: onInnerChange,
      close: close
    }
  }, /*#__PURE__*/React.createElement("div", {
    ref: root,
    className: clsx(bem(), props.className),
    style: _extends({}, props.style)
  }, /*#__PURE__*/React.createElement("div", {
    ref: barRef,
    style: barStyle(),
    className: clsx(bem('bar', {
      opened: opened
    }))
  }, childrenRefs.map(renderTitle)), Children.toArray(props.children).filter(Boolean).map(function (child, index) {
    return /*#__PURE__*/cloneElement(child, {
      ref: setChildrenRefs(index),
      offset: offset.current,
      showPopup: showPopupIndex === index
    });
  })));
});
DropdownMenu.defaultProps = {
  duration: 200,
  overlay: true,
  closeOnClickOutside: true,
  closeOnClickOverlay: true,
  direction: 'down',
  defaultValue: {}
};
export default DropdownMenu;