"use strict";

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

exports.__esModule = true;
exports.default = void 0;

var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));

var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));

var _react = _interopRequireWildcard(require("react"));

var _propTypes = _interopRequireDefault(require("prop-types"));

var _isNil = _interopRequireDefault(require("lodash/isNil"));

var _Spinner = _interopRequireDefault(require("@rsuite/icons/legacy/Spinner"));

var _AngleLeft = _interopRequireDefault(require("@rsuite/icons/legacy/AngleLeft"));

var _AngleRight = _interopRequireDefault(require("@rsuite/icons/legacy/AngleRight"));

var _utils = require("../utils");

var _Picker = require("../Picker");

var _utils2 = require("./utils");

var defaultProps = {
  as: 'div',
  disabledItemValues: [],
  uncheckableItemValues: [],
  cascadeData: [],
  cascadePaths: [],
  menuWidth: 156,
  menuHeight: 200,
  childrenKey: 'children',
  valueKey: 'value',
  labelKey: 'label'
};

var DropdownMenu = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
  var Component = props.as,
      classPrefix = props.classPrefix,
      className = props.className,
      cascade = props.cascade,
      cascadeData = props.cascadeData,
      cascadePaths = props.cascadePaths,
      childrenKey = props.childrenKey,
      disabledItemValues = props.disabledItemValues,
      menuWidth = props.menuWidth,
      menuHeight = props.menuHeight,
      uncheckableItemValues = props.uncheckableItemValues,
      value = props.value,
      valueKey = props.valueKey,
      labelKey = props.labelKey,
      loadingText = props.loadingText,
      renderMenuItem = props.renderMenuItem,
      renderMenu = props.renderMenu,
      _onCheck = props.onCheck,
      onSelect = props.onSelect,
      rest = (0, _objectWithoutPropertiesLoose2.default)(props, ["as", "classPrefix", "className", "cascade", "cascadeData", "cascadePaths", "childrenKey", "disabledItemValues", "menuWidth", "menuHeight", "uncheckableItemValues", "value", "valueKey", "labelKey", "loadingText", "renderMenuItem", "renderMenu", "onCheck", "onSelect"]);

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

  var classes = merge(className, prefix('items'));
  var rtl = (0, _utils.useCustom)('DropdownMenu');
  var getCascadeItems = (0, _react.useCallback)(function (items, layer, node, isLeafNode) {
    var data = [];
    var paths = [];

    for (var i = 0; i < cascadeData.length && i < layer; i += 1) {
      data.push(cascadeData[i]);

      if (i < layer - 1 && cascadePaths) {
        paths.push(cascadePaths[i]);
      }
    }

    paths.push(node);

    if (!isLeafNode) {
      data.push(items);
    }

    return {
      cascadeData: data,
      cascadePaths: paths
    };
  }, [cascadeData, cascadePaths]);
  var handleSelect = (0, _react.useCallback)(function (layer, node, event) {
    var children = node[childrenKey];
    var isLeafNode = (0, _isNil.default)(children);
    var items = (children || []).map(function (item) {
      return (0, _extends2.default)({}, item, {
        parent: node
      });
    });

    var _getCascadeItems = getCascadeItems(items, layer + 1, node, isLeafNode),
        cascadeData = _getCascadeItems.cascadeData,
        cascadePaths = _getCascadeItems.cascadePaths;

    onSelect === null || onSelect === void 0 ? void 0 : onSelect(node, cascadeData, cascadePaths, event);
  }, [childrenKey, getCascadeItems, onSelect]);

  var renderCascadeNode = function renderCascadeNode(node, index, layer, focus, uncheckable) {
    var children = node[childrenKey];
    var nodeValue = node[valueKey];
    var nodeLabel = node[labelKey];
    var disabled = disabledItemValues.some(function (disabledValue) {
      return (0, _utils.shallowEqual)(disabledValue, nodeValue);
    }); // Use `value` in keys when If `value` is string or number

    var onlyKey = typeof value === 'number' || typeof value === 'string' ? value : index;
    var Icon = rtl ? _AngleRight.default : _AngleLeft.default;
    var active = value.some(function (v) {
      return v === nodeValue;
    });

    if (cascade) {
      active = active || (0, _utils2.isSomeParentChecked)(node, value, {
        valueKey: valueKey
      });
    }

    return /*#__PURE__*/_react.default.createElement(_Picker.DropdownMenuCheckItem, {
      as: "li",
      key: layer + "-" + onlyKey,
      disabled: disabled,
      active: active,
      focus: focus // Pass the node as a value to Item, and use it in event callbacks.
      ,
      value: nodeValue,
      className: children ? prefix('has-children') : undefined,
      indeterminate: cascade && !active && (0, _utils2.isSomeChildChecked)(node, value, {
        valueKey: valueKey,
        childrenKey: childrenKey
      }),
      onSelectItem: function onSelectItem(_value, event) {
        return handleSelect(layer, node, event);
      },
      onCheck: function onCheck(_value, event, checked) {
        return _onCheck === null || _onCheck === void 0 ? void 0 : _onCheck(node, event, checked);
      },
      checkable: !uncheckable
    }, renderMenuItem ? renderMenuItem(nodeLabel, node) : nodeLabel, children ? /*#__PURE__*/_react.default.createElement(Icon, {
      className: prefix('caret')
    }) : null);
  };

  var renderCascade = function renderCascade() {
    var styles = {
      width: cascadeData.length * menuWidth
    };
    var columnStyles = {
      height: menuHeight,
      width: menuWidth
    };
    var cascadeNodes = cascadeData.map(function (children, layer) {
      var uncheckableCount = 0;
      var onlyKey = layer + "_" + children.length;

      var menu = /*#__PURE__*/_react.default.createElement("ul", {
        role: "listbox"
      }, children.map(function (item, index) {
        var uncheckable = uncheckableItemValues.some(function (uncheckableValue) {
          return (0, _utils.shallowEqual)(uncheckableValue, item[valueKey]);
        });

        if (uncheckable) {
          uncheckableCount++;
        }

        return renderCascadeNode(item, index, layer, cascadePaths[layer] && (0, _utils.shallowEqual)(cascadePaths[layer][valueKey], item[valueKey]), uncheckable);
      }));

      var parentNode = cascadePaths[layer - 1];
      var columnClasses = prefix('column', {
        'column-uncheckable': uncheckableCount === children.length
      });

      var renderMenuElement = function renderMenuElement() {
        if (renderMenu) {
          return renderMenu(children, menu, parentNode);
        }

        return (parentNode === null || parentNode === void 0 ? void 0 : parentNode.loading) ? /*#__PURE__*/_react.default.createElement("div", {
          className: prefix('column-loading')
        }, /*#__PURE__*/_react.default.createElement(_Spinner.default, {
          spin: true
        }), " ", /*#__PURE__*/_react.default.createElement("span", null, loadingText)) : menu;
      };

      var node = /*#__PURE__*/_react.default.createElement("div", {
        key: onlyKey,
        className: columnClasses,
        "data-layer": layer,
        style: columnStyles
      }, renderMenuElement());

      return node;
    });
    return /*#__PURE__*/_react.default.createElement("div", {
      style: styles
    }, cascadeNodes);
  };

  return /*#__PURE__*/_react.default.createElement(Component, (0, _extends2.default)({}, rest, {
    ref: ref,
    className: classes
  }), renderCascade());
});

DropdownMenu.displayName = 'DropdownMenu';
DropdownMenu.defaultProps = defaultProps;
DropdownMenu.propTypes = {
  classPrefix: _propTypes.default.string,
  data: _propTypes.default.array,
  disabledItemValues: _propTypes.default.array,
  value: _propTypes.default.array,
  childrenKey: _propTypes.default.string,
  valueKey: _propTypes.default.string,
  labelKey: _propTypes.default.string,
  menuWidth: _propTypes.default.number,
  menuHeight: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),
  className: _propTypes.default.string,
  cascade: _propTypes.default.bool,
  cascadeData: _propTypes.default.array,
  cascadePaths: _propTypes.default.array,
  uncheckableItemValues: _propTypes.default.array,
  renderMenuItem: _propTypes.default.func,
  renderMenu: _propTypes.default.func,
  onSelect: _propTypes.default.func,
  onCheck: _propTypes.default.func
};
var _default = DropdownMenu;
exports.default = _default;