"use strict";

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

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

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

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

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 _clone = _interopRequireDefault(require("lodash/clone"));

var _isUndefined = _interopRequireDefault(require("lodash/isUndefined"));

var _isFunction = _interopRequireDefault(require("lodash/isFunction"));

var _remove = _interopRequireDefault(require("lodash/remove"));

var _omit = _interopRequireDefault(require("lodash/omit"));

var _pick = _interopRequireDefault(require("lodash/pick"));

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

var _treeUtils = require("../utils/treeUtils");

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

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

function _templateObject() {
  var data = (0, _taggedTemplateLiteralLoose2.default)(["none"]);

  _templateObject = function _templateObject() {
    return data;
  };

  return data;
}

var defaultProps = {
  as: 'div',
  appearance: 'default',
  classPrefix: 'picker',
  countable: true,
  searchable: true,
  cleanable: true,
  data: [],
  disabledItemValues: [],
  valueKey: 'value',
  labelKey: 'label',
  placement: 'bottomStart',
  menuAutoWidth: true,
  menuMaxHeight: 320
};

var CheckPicker = /*#__PURE__*/_react.default.forwardRef(function (props, ref) {
  var Component = props.as,
      classPrefix = props.classPrefix,
      countable = props.countable,
      data = props.data,
      disabledItemValues = props.disabledItemValues,
      valueKey = props.valueKey,
      labelKey = props.labelKey,
      searchable = props.searchable,
      virtualized = props.virtualized,
      cleanable = props.cleanable,
      placement = props.placement,
      menuAutoWidth = props.menuAutoWidth,
      menuMaxHeight = props.menuMaxHeight,
      menuClassName = props.menuClassName,
      menuStyle = props.menuStyle,
      overrideLocale = props.locale,
      placeholder = props.placeholder,
      disabled = props.disabled,
      toggleAs = props.toggleAs,
      style = props.style,
      sticky = props.sticky,
      valueProp = props.value,
      defaultValue = props.defaultValue,
      groupBy = props.groupBy,
      listProps = props.listProps,
      id = props.id,
      sort = props.sort,
      searchBy = props.searchBy,
      renderMenuItem = props.renderMenuItem,
      renderMenuGroup = props.renderMenuGroup,
      renderValue = props.renderValue,
      renderExtraFooter = props.renderExtraFooter,
      renderMenu = props.renderMenu,
      onGroupTitleClick = props.onGroupTitleClick,
      onSearch = props.onSearch,
      onEnter = props.onEnter,
      onEntered = props.onEntered,
      onExited = props.onExited,
      onClean = props.onClean,
      onChange = props.onChange,
      onSelect = props.onSelect,
      onClose = props.onClose,
      onOpen = props.onOpen,
      rest = (0, _objectWithoutPropertiesLoose2.default)(props, ["as", "classPrefix", "countable", "data", "disabledItemValues", "valueKey", "labelKey", "searchable", "virtualized", "cleanable", "placement", "menuAutoWidth", "menuMaxHeight", "menuClassName", "menuStyle", "locale", "placeholder", "disabled", "toggleAs", "style", "sticky", "value", "defaultValue", "groupBy", "listProps", "id", "sort", "searchBy", "renderMenuItem", "renderMenuGroup", "renderValue", "renderExtraFooter", "renderMenu", "onGroupTitleClick", "onSearch", "onEnter", "onEntered", "onExited", "onClean", "onChange", "onSelect", "onClose", "onOpen"]);
  var triggerRef = (0, _react.useRef)();
  var targetRef = (0, _react.useRef)();
  var overlayRef = (0, _react.useRef)();

  var _useCustom = (0, _utils.useCustom)('Picker', overrideLocale),
      locale = _useCustom.locale;

  var _useControlled = (0, _utils.useControlled)(valueProp, defaultValue || []),
      value = _useControlled[0],
      setValue = _useControlled[1]; // Used to hover the focuse item  when trigger `onKeydown`


  var _useFocusItemValue = (0, _Picker.useFocusItemValue)(value === null || value === void 0 ? void 0 : value[0], {
    data: data,
    valueKey: valueKey,
    target: function target() {
      return overlayRef.current;
    }
  }),
      focusItemValue = _useFocusItemValue.focusItemValue,
      setFocusItemValue = _useFocusItemValue.setFocusItemValue,
      onFocusItem = _useFocusItemValue.onKeyDown;

  var handleSearchCallback = (0, _react.useCallback)(function (searchKeyword, filteredData, event) {
    var _filteredData$;

    // The first option after filtering is the focus.
    setFocusItemValue(filteredData === null || filteredData === void 0 ? void 0 : (_filteredData$ = filteredData[0]) === null || _filteredData$ === void 0 ? void 0 : _filteredData$[valueKey]);
    onSearch === null || onSearch === void 0 ? void 0 : onSearch(searchKeyword, event);
  }, [setFocusItemValue, onSearch, valueKey]); // Use search keywords to filter options.

  var _useSearch = (0, _Picker.useSearch)({
    labelKey: labelKey,
    data: data,
    searchBy: searchBy,
    callback: handleSearchCallback
  }),
      searchKeyword = _useSearch.searchKeyword,
      filteredData = _useSearch.filteredData,
      setSearchKeyword = _useSearch.setSearchKeyword,
      handleSearch = _useSearch.handleSearch,
      checkShouldDisplay = _useSearch.checkShouldDisplay; // Use component active state to support keyboard events.


  var _useState = (0, _react.useState)(false),
      active = _useState[0],
      setActive = _useState[1]; // A list of shortcut options.
  // when opened again, the selected options are displayed at the top.


  var _useState2 = (0, _react.useState)([]),
      stickyItems = _useState2[0],
      setStickyItems = _useState2[1];

  var initStickyItems = function initStickyItems() {
    if (!sticky) {
      return;
    }

    var nextStickyItems = [];

    if (data && value.length) {
      nextStickyItems = data.filter(function (item) {
        return value.some(function (v) {
          return v === item[valueKey];
        });
      });
    }

    setStickyItems(nextStickyItems);
  };

  var handleChangeValue = (0, _react.useCallback)(function (value, event) {
    onChange === null || onChange === void 0 ? void 0 : onChange(value, event);
  }, [onChange]);
  var handleClean = (0, _react.useCallback)(function (event) {
    if (disabled || !cleanable) {
      return;
    }

    setValue([]);
    handleChangeValue([], event);
  }, [disabled, cleanable, setValue, handleChangeValue]);

  var handleMenuPressEnter = function handleMenuPressEnter(event) {
    var nextValue = (0, _clone.default)(value);

    if (!focusItemValue) {
      return;
    }

    if (!nextValue.some(function (v) {
      return (0, _utils.shallowEqual)(v, focusItemValue);
    })) {
      nextValue.push(focusItemValue);
    } else {
      (0, _remove.default)(nextValue, function (itemVal) {
        return (0, _utils.shallowEqual)(itemVal, focusItemValue);
      });
    }

    var focusItem = data.find(function (item) {
      return (0, _utils.shallowEqual)(item === null || item === void 0 ? void 0 : item[valueKey], focusItemValue);
    });
    setValue(nextValue);
    handleSelect(nextValue, focusItem, event);
    handleChangeValue(nextValue, event);
  };

  var onPickerKeyDown = (0, _Picker.useToggleKeyDownEvent)((0, _extends2.default)({
    toggle: !focusItemValue || !active,
    triggerRef: triggerRef,
    targetRef: targetRef,
    overlayRef: overlayRef,
    active: active,
    onExit: handleClean,
    onMenuKeyDown: onFocusItem,
    onMenuPressEnter: handleMenuPressEnter,
    onClose: function onClose() {
      setFocusItemValue(null);
    }
  }, rest));
  var handleSelect = (0, _react.useCallback)(function (nextItemValue, item, event) {
    onSelect === null || onSelect === void 0 ? void 0 : onSelect(nextItemValue, item, event);
  }, [onSelect]);
  var handleItemSelect = (0, _react.useCallback)(function (nextItemValue, item, event, checked) {
    var nextValue = (0, _clone.default)(value);

    if (checked) {
      nextValue.push(nextItemValue);
    } else {
      (0, _remove.default)(nextValue, function (itemVal) {
        return (0, _utils.shallowEqual)(itemVal, nextItemValue);
      });
    }

    setValue(nextValue);
    setFocusItemValue(nextItemValue);
    handleSelect(nextValue, item, event);
    handleChangeValue(nextValue, event);
  }, [value, setValue, handleSelect, handleChangeValue, setFocusItemValue]);
  var handleEntered = (0, _react.useCallback)(function () {
    setActive(true);
    onOpen === null || onOpen === void 0 ? void 0 : onOpen();
  }, [onOpen]);
  var handleExited = (0, _react.useCallback)(function () {
    setSearchKeyword('');
    setFocusItemValue(null);
    setActive(false);
    onClose === null || onClose === void 0 ? void 0 : onClose();
  }, [onClose, setFocusItemValue, setSearchKeyword]);
  (0, _Picker.usePublicMethods)(ref, {
    triggerRef: triggerRef,
    overlayRef: overlayRef,
    targetRef: targetRef
  });
  var selectedItems = data.filter(function (item) {
    return value === null || value === void 0 ? void 0 : value.some(function (val) {
      return (0, _utils.shallowEqual)(item[valueKey], val);
    });
  }) || [];
  /**
   * 1.Have a value and the value is valid.
   * 2.Regardless of whether the value is valid, as long as renderValue is set, it is judged to have a value.
   */

  var hasValue = selectedItems.length > 0 || (value === null || value === void 0 ? void 0 : value.length) > 0 && (0, _isFunction.default)(renderValue);

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

  var selectedElement = placeholder;

  if (selectedItems.length > 0) {
    selectedElement = /*#__PURE__*/_react.default.createElement(_Picker.SelectedElement, {
      selectedItems: selectedItems,
      countable: countable,
      valueKey: valueKey,
      labelKey: labelKey,
      prefix: prefix
    });
  }

  if ((value === null || value === void 0 ? void 0 : value.length) > 0 && (0, _isFunction.default)(renderValue)) {
    selectedElement = renderValue(value, selectedItems, selectedElement); // If renderValue returns null or undefined, hasValue is false.

    if ((0, _isNil.default)(selectedElement)) {
      hasValue = false;
    }
  }

  var renderDropdownMenu = function renderDropdownMenu(positionProps, speakerRef) {
    var left = positionProps.left,
        top = positionProps.top,
        className = positionProps.className;
    var classes = merge(className, menuClassName, prefix('check-menu'));
    var styles = (0, _extends2.default)({}, menuStyle, {
      left: left,
      top: top
    });
    var items = filteredData;
    var filteredStickyItems = [];

    if (stickyItems) {
      filteredStickyItems = (0, _treeUtils.filterNodesOfTree)(stickyItems, function (item) {
        return checkShouldDisplay(item);
      });
      items = (0, _treeUtils.filterNodesOfTree)(data, function (item) {
        return checkShouldDisplay(item) && !stickyItems.some(function (v) {
          return v[valueKey] === item[valueKey];
        });
      });
    } // Create a tree structure data when set `groupBy`


    if (groupBy) {
      items = (0, _utils.getDataGroupBy)(items, groupBy, sort);
    } else if (typeof sort === 'function') {
      items = items.sort(sort(false));
    }

    var menu = items.length || filteredStickyItems.length ? /*#__PURE__*/_react.default.createElement(_Picker.DropdownMenu, {
      id: id ? id + "-listbox" : undefined,
      listProps: listProps,
      disabledItemValues: disabledItemValues,
      valueKey: valueKey,
      labelKey: labelKey,
      renderMenuGroup: renderMenuGroup,
      renderMenuItem: renderMenuItem,
      maxHeight: menuMaxHeight,
      classPrefix: 'picker-check-menu',
      dropdownMenuItemAs: _Picker.DropdownMenuCheckItem,
      activeItemValues: value,
      focusItemValue: focusItemValue,
      data: [].concat(filteredStickyItems, items),
      group: !(0, _isUndefined.default)(groupBy),
      onSelect: handleItemSelect,
      onGroupTitleClick: onGroupTitleClick,
      virtualized: virtualized
    }) : /*#__PURE__*/_react.default.createElement("div", {
      className: prefix(_templateObject())
    }, locale === null || locale === void 0 ? void 0 : locale.noResultsText);
    return /*#__PURE__*/_react.default.createElement(_Picker.PickerOverlay, {
      ref: (0, _utils.mergeRefs)(overlayRef, speakerRef),
      autoWidth: menuAutoWidth,
      className: classes,
      style: styles,
      onKeyDown: onPickerKeyDown,
      target: triggerRef
    }, searchable && /*#__PURE__*/_react.default.createElement(_Picker.SearchBar, {
      placeholder: locale === null || locale === void 0 ? void 0 : locale.searchPlaceholder,
      onChange: handleSearch,
      value: searchKeyword
    }), renderMenu ? renderMenu(menu) : menu, renderExtraFooter === null || renderExtraFooter === void 0 ? void 0 : renderExtraFooter());
  };

  var _usePickerClassName = (0, _Picker.usePickerClassName)((0, _extends2.default)({}, props, {
    hasValue: hasValue,
    name: 'check'
  })),
      classes = _usePickerClassName[0],
      usedClassNamePropKeys = _usePickerClassName[1];

  return /*#__PURE__*/_react.default.createElement(_Picker.PickerToggleTrigger, {
    pickerProps: (0, _pick.default)(props, _Picker.pickTriggerPropKeys),
    ref: triggerRef,
    placement: placement,
    onEnter: (0, _utils.createChainedFunction)(initStickyItems, onEnter),
    onEntered: (0, _utils.createChainedFunction)(handleEntered, onEntered),
    onExited: (0, _utils.createChainedFunction)(handleExited, onExited),
    speaker: renderDropdownMenu
  }, /*#__PURE__*/_react.default.createElement(Component, {
    className: classes,
    style: style
  }, /*#__PURE__*/_react.default.createElement(_Picker.PickerToggle, (0, _extends2.default)({}, (0, _omit.default)(rest, [].concat(_Picker.omitTriggerPropKeys, usedClassNamePropKeys)), {
    id: id,
    ref: targetRef,
    disabled: disabled,
    onClean: (0, _utils.createChainedFunction)(handleClean, onClean),
    onKeyDown: onPickerKeyDown,
    as: toggleAs,
    cleanable: cleanable && !disabled,
    hasValue: hasValue,
    active: active,
    placement: placement,
    inputValue: value
  }), selectedElement || (locale === null || locale === void 0 ? void 0 : locale.placeholder))));
});

CheckPicker.displayName = 'CheckPicker';
CheckPicker.defaultProps = defaultProps;
CheckPicker.propTypes = (0, _extends2.default)({}, _Picker.listPickerPropTypes, {
  locale: _propTypes.default.any,
  appearance: _propTypes.default.oneOf(['default', 'subtle']),
  menuAutoWidth: _propTypes.default.bool,
  menuMaxHeight: _propTypes.default.number,
  renderMenu: _propTypes.default.func,
  renderMenuItem: _propTypes.default.func,
  renderMenuGroup: _propTypes.default.func,
  onSelect: _propTypes.default.func,
  onGroupTitleClick: _propTypes.default.func,
  onSearch: _propTypes.default.func,
  groupBy: _propTypes.default.any,
  sort: _propTypes.default.func,
  searchable: _propTypes.default.bool,
  countable: _propTypes.default.bool,
  sticky: _propTypes.default.bool,
  virtualized: _propTypes.default.bool,
  searchBy: _propTypes.default.func
});
var _default = CheckPicker;
exports.default = _default;