"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _difference2 = _interopRequireDefault(require("lodash/difference"));
var _isEmpty2 = _interopRequireDefault(require("lodash/isEmpty"));
var _isString2 = _interopRequireDefault(require("lodash/isString"));
var _isUndefined2 = _interopRequireDefault(require("lodash/isUndefined"));
var _get2 = _interopRequireDefault(require("lodash/get"));
var _isFunction2 = _interopRequireDefault(require("lodash/isFunction"));
var _isNumber2 = _interopRequireDefault(require("lodash/isNumber"));
var _constants = require("../treeSelect/constants");
var _foundation = _interopRequireDefault(require("../base/foundation"));
var _treeUtil = require("../tree/treeUtil");
var _isEnterPress = _interopRequireDefault(require("../utils/isEnterPress"));
var _keyCode = require("../utils/keyCode");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
class TreeSelectFoundation extends _foundation.default {
  constructor(adapter) {
    super(Object.assign({}, adapter));
    this.handleKeyDown = e => {
      if (e.key === _keyCode.ESC_KEY) {
        const isOpen = this.getState('isOpen');
        isOpen && this.close(e);
      }
    };
    this._registerClickOutsideHandler = () => {
      this._adapter.registerClickOutsideHandler(e => {
        this.handlerTriggerBlur(e);
        this.close(e);
      });
    };
    this.clearInputValue = () => {
      const {
        inputValue
      } = this.getStates();
      inputValue && this._adapter.updateInputValue('');
    };
    this.onClickSingleTriggerSearchItem = e => {
      this.focusInput(true);
    };
  }
  init() {
    const {
      searchAutoFocus,
      searchPosition,
      filterTreeNode
    } = this.getProps();
    const triggerSearch = searchPosition === _constants.strings.SEARCH_POSITION_TRIGGER && filterTreeNode;
    const triggerSearchAutoFocus = searchAutoFocus && triggerSearch;
    this._setDropdownWidth();
    const able = !this._isDisabled();
    const isOpen = (this.getProp('defaultOpen') || triggerSearchAutoFocus) && able;
    if (isOpen) {
      this.open();
      this._registerClickOutsideHandler();
    }
    if (triggerSearchAutoFocus && able) {
      this.handleTriggerFocus(null);
    }
  }
  destroy() {
    // Ensure that event monitoring will be uninstalled, and the user may not trigger closePanel
    this._adapter.unregisterClickOutsideHandler();
  }
  _setDropdownWidth() {
    const {
      style,
      dropdownMatchSelectWidth
    } = this.getProps();
    let width;
    if (dropdownMatchSelectWidth) {
      if (style && (0, _isNumber2.default)(style.width)) {
        width = style.width;
      } else if (style && (0, _isString2.default)(style.width) && !style.width.includes('%')) {
        width = style.width;
      } else {
        width = this._adapter.getTriggerWidth();
      }
      this._adapter.setOptionWrapperWidth(width);
    }
  }
  _isMultiple() {
    return this.getProp('multiple');
  }
  _isAnimated() {
    return this.getProp('motionExpand');
  }
  _isDisabled() {
    let treeNode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
    return this.getProp('disabled') || treeNode.disabled;
  }
  _isExpandControlled() {
    return this.getProp('expandedKeys');
  }
  _isSelectToClose() {
    return !this.getProp('expandAction');
  }
  _isLoadControlled() {
    return this.getProp('loadedKeys');
  }
  _showFilteredOnly() {
    const {
      inputValue
    } = this.getStates();
    const {
      showFilteredOnly
    } = this.getProps();
    return Boolean(inputValue) && showFilteredOnly;
  }
  findDataForValue(findValue) {
    const {
      value,
      defaultValue,
      keyMaps
    } = this.getProps();
    const realValueName = (0, _get2.default)(keyMaps, 'value', 'value');
    const realKeyName = (0, _get2.default)(keyMaps, 'key', 'key');
    let valueArr = [];
    if (value) {
      valueArr = Array.isArray(value) ? value : [value];
    } else if (defaultValue) {
      valueArr = Array.isArray(defaultValue) ? defaultValue : [defaultValue];
    }
    return valueArr.find(item => {
      return item[realValueName] === findValue || item[realKeyName] === findValue;
    });
  }
  constructDataForValue(value) {
    const {
      treeNodeLabelProp,
      keyMaps
    } = this.getProps();
    const keyName = (0, _get2.default)(keyMaps, 'key', 'key');
    const labelName = (0, _get2.default)(keyMaps, 'label', treeNodeLabelProp);
    return {
      [keyName]: value,
      [labelName]: value
    };
  }
  getDataForKeyNotInKeyEntities(value) {
    const {
      onChangeWithObject
    } = this.getProps();
    if (onChangeWithObject) {
      return this.findDataForValue(value);
    } else {
      return this.constructDataForValue(value);
    }
  }
  getTreeNodeProps(key) {
    const {
      expandedKeys = new Set([]),
      selectedKeys = [],
      checkedKeys = new Set([]),
      halfCheckedKeys = new Set([]),
      realCheckedKeys = new Set([]),
      keyEntities = {},
      filteredKeys = new Set([]),
      inputValue = '',
      loadedKeys,
      loadingKeys,
      filteredExpandedKeys = new Set([]),
      disabledKeys = new Set([])
    } = this.getStates();
    const {
      treeNodeFilterProp,
      checkRelation
    } = this.getProps();
    const entity = keyEntities[key];
    const notExist = !entity;
    if (notExist) {
      return null;
    }
    // if checkRelation is invalid, the checked status of node will be false
    let realChecked = false;
    let realHalfChecked = false;
    if (checkRelation === 'related') {
      realChecked = checkedKeys.has(key);
      realHalfChecked = halfCheckedKeys.has(key);
    } else if (checkRelation === 'unRelated') {
      realChecked = realCheckedKeys.has(key);
      realHalfChecked = false;
    }
    const isSearching = Boolean(inputValue);
    const treeNodeProps = {
      eventKey: key,
      expanded: isSearching ? filteredExpandedKeys.has(key) : expandedKeys.has(key),
      selected: selectedKeys.includes(key),
      checked: realChecked,
      halfChecked: realHalfChecked,
      pos: String(entity ? entity.pos : ''),
      level: entity.level,
      filtered: filteredKeys.has(key),
      keyword: inputValue,
      treeNodeFilterProp,
      loading: loadingKeys.has(key) && !loadedKeys.has(key),
      loaded: loadedKeys.has(key)
    };
    if (this.getProp('disableStrictly') && disabledKeys.has(key)) {
      treeNodeProps.disabled = true;
    }
    return treeNodeProps;
  }
  handleNodeLoad(loadedKeys, loadingKeys, data, resolve) {
    const {
      loadData
    } = this.getProps();
    const {
      key
    } = data;
    if (!loadData || loadedKeys.has(key) || loadingKeys.has(key)) {
      return {};
    }
    loadData(data).then(() => {
      const prevLoadedKeys = new Set(this.getState('loadedKeys'));
      const prevLoadingKeys = new Set(this.getState('loadingKeys'));
      const newLoadedKeys = prevLoadedKeys.add(key);
      const newLoadingKeys = new Set([...prevLoadingKeys]);
      newLoadingKeys.delete(key);
      this._adapter.notifyLoad(newLoadedKeys, data);
      if (!this._isLoadControlled()) {
        this._adapter.updateState({
          loadedKeys: newLoadedKeys
        });
      }
      this._adapter.setState({
        loadingKeys: newLoadingKeys
      });
      resolve();
    });
    return {
      loadingKeys: loadingKeys.add(key)
    };
  }
  /* istanbul ignore next */
  focusInput(bool) {
    this._adapter.updateInputFocus(bool);
  }
  _notifyMultipleChange(key, e) {
    const {
      keyEntities
    } = this.getStates();
    const {
      leafOnly,
      checkRelation,
      keyMaps,
      autoMergeValue
    } = this.getProps();
    let keyList = [];
    if (checkRelation === 'related') {
      keyList = autoMergeValue ? (0, _treeUtil.normalizeKeyList)(key, keyEntities, leafOnly, true) : key;
    } else if (checkRelation === 'unRelated') {
      keyList = key;
    }
    const nodes = keyList.map(key => keyEntities[key] && keyEntities[key].key === key ? keyEntities[key].data : this.getDataForKeyNotInKeyEntities(key));
    if (this.getProp('onChangeWithObject')) {
      this._adapter.notifyChangeWithObject(nodes, e);
    } else {
      const value = (0, _treeUtil.getValueOrKey)(nodes, keyMaps);
      this._adapter.notifyChange(value, nodes, e);
    }
  }
  _notifyChange(key, e) {
    const {
      keyEntities
    } = this.getStates();
    const {
      keyMaps
    } = this.getProps();
    if (this._isMultiple() && Array.isArray(key)) {
      this._notifyMultipleChange(key, e);
    } else {
      const nodes = (0, _isUndefined2.default)(key) ? key : keyEntities[key].data;
      const value = (0, _isUndefined2.default)(key) ? key : (0, _treeUtil.getValueOrKey)(nodes, keyMaps);
      if (this.getProp('onChangeWithObject')) {
        this._adapter.notifyChangeWithObject(nodes, e);
      } else {
        this._adapter.notifyChange(value, nodes, e);
      }
    }
  }
  // Scenes that may trigger focus:
  //  1、click selection
  _notifyFocus(e) {
    this._adapter.notifyFocus(e);
  }
  handleTriggerFocus(e) {
    this._adapter.updateIsFocus(true);
    this._notifyFocus(e);
    this._registerClickOutsideHandler();
  }
  // Scenes that may trigger blur
  //  1、clickOutSide
  //  2、click option / press enter, and then select complete（when multiple is false
  //  3、press esc when dropdown list open
  _notifyBlur(e) {
    this._adapter.notifyBlur(e);
  }
  handlerTriggerBlur(e) {
    const isFocus = this.getState('isFocus');
    if (!isFocus) {
      return;
    }
    this._adapter.updateIsFocus(false);
    this._notifyBlur(e);
    this._adapter.unregisterClickOutsideHandler();
  }
  toggleHoverState(bool) {
    this._adapter.toggleHovering(bool);
  }
  open() {
    this._adapter.openMenu();
    this._setDropdownWidth();
  }
  close(e) {
    this._adapter.closeMenu();
    if (this.getProp('motionExpand')) {
      this._adapter.updateState({
        motionKeys: new Set([])
      });
    }
  }
  handleClick(e) {
    const isDisabled = this._isDisabled();
    const {
      isOpen,
      inputValue,
      isFocus
    } = this.getStates();
    const {
      searchPosition,
      clickTriggerToHide
    } = this.getProps();
    if (isDisabled) {
      return;
    } else {
      if (!isFocus) {
        this.handleTriggerFocus(e);
      }
      if (isOpen) {
        if (searchPosition === 'trigger' && inputValue) {
          return;
        }
        clickTriggerToHide && this.close(e);
      } else {
        this.open();
      }
    }
  }
  /**
   * A11y: simulate selection click
   */
  /* istanbul ignore next */
  handleSelectionEnterPress(e) {
    if ((0, _isEnterPress.default)(e)) {
      this.handleClick(e);
    }
  }
  handleClear(e) {
    const {
      searchPosition,
      filterTreeNode
    } = this.getProps();
    const {
      inputValue,
      selectedKeys
    } = this.getStates();
    const isMultiple = this._isMultiple();
    const isControlled = this._isControlledComponent();
    const value = isMultiple ? [] : undefined;
    this._notifyChange(value, e);
    if (!isControlled) {
      // reposition dropdown when selected values change
      this._adapter.rePositionDropdown();
      this._adapter.updateState({
        selectedKeys: [],
        checkedKeys: new Set(),
        halfCheckedKeys: new Set(),
        realCheckedKeys: new Set([])
      });
    }
    // When triggerSearch, clicking the clear button will trigger to clear Input
    if (filterTreeNode && searchPosition === _constants.strings.SEARCH_POSITION_TRIGGER) {
      if (inputValue !== '') {
        if ((0, _isEmpty2.default)(selectedKeys)) {
          this.handleInputChange('');
        } else {
          this.clearInput();
        }
      }
    }
    this._adapter.notifyClear(e);
  }
  /**
   * A11y: simulate clear button click
   */
  /* istanbul ignore next */
  handleClearEnterPress(e) {
    if ((0, _isEnterPress.default)(e)) {
      this.handleClear(e);
    }
  }
  removeTag(eventKey) {
    const {
      disableStrictly,
      checkRelation,
      keyMaps
    } = this.getProps();
    const {
      keyEntities,
      disabledKeys,
      realCheckedKeys
    } = this.getStates();
    const item = keyEntities[eventKey] && keyEntities[eventKey].key === eventKey ? keyEntities[eventKey].data : this.getDataForKeyNotInKeyEntities(eventKey);
    const disabledName = (0, _get2.default)(keyMaps, 'disabled', 'disabled');
    if (item[disabledName] || disableStrictly && disabledKeys.has(eventKey)) {
      return;
    }
    if (checkRelation === 'unRelated') {
      const newRealCheckedKeys = new Set(realCheckedKeys);
      newRealCheckedKeys.delete(eventKey);
      this._notifyChange([...newRealCheckedKeys], null);
      if (!this._isControlledComponent()) {
        this._adapter.updateState({
          realCheckedKeys: newRealCheckedKeys
        });
        this._adapter.rePositionDropdown();
      }
    } else if (checkRelation === 'related') {
      const {
        checkedKeys,
        halfCheckedKeys
      } = this.calcCheckedKeys(eventKey, false);
      this._notifyChange([...checkedKeys], null);
      if (!this._isControlledComponent()) {
        this._adapter.updateState({
          checkedKeys,
          halfCheckedKeys
        });
        this._adapter.rePositionDropdown();
      }
    }
    this._adapter.notifySelect(eventKey, false, item);
    // reposition dropdown when selected values change
    this._adapter.rePositionDropdown();
  }
  clearInput() {
    const {
      flattenNodes,
      expandedKeys,
      selectedKeys,
      keyEntities,
      treeData
    } = this.getStates();
    const {
      keyMaps
    } = this.getProps();
    const newExpandedKeys = new Set(expandedKeys);
    const isExpandControlled = this._isExpandControlled();
    const expandedOptsKeys = (0, _treeUtil.findAncestorKeys)(selectedKeys, keyEntities, false);
    expandedOptsKeys.forEach(item => newExpandedKeys.add(item));
    const newFlattenNodes = (0, _treeUtil.flattenTreeData)(treeData, newExpandedKeys, keyMaps);
    this._adapter.updateState({
      expandedKeys: newExpandedKeys,
      flattenNodes: newFlattenNodes,
      inputValue: '',
      motionKeys: new Set([]),
      filteredKeys: new Set([]),
      filteredExpandedKeys: new Set(expandedOptsKeys),
      filteredShownKeys: new Set([])
    });
    this._adapter.rePositionDropdown();
  }
  handleInputChange(sugInput) {
    // Input is used as controlled component
    this._adapter.updateInputValue(sugInput);
    const {
      flattenNodes,
      expandedKeys,
      selectedKeys,
      keyEntities,
      treeData
    } = this.getStates();
    const {
      showFilteredOnly,
      filterTreeNode,
      treeNodeFilterProp,
      keyMaps
    } = this.getProps();
    const realFilterProp = treeNodeFilterProp !== 'label' ? treeNodeFilterProp : (0, _get2.default)(keyMaps, 'label', 'label');
    const newExpandedKeys = new Set(expandedKeys);
    let filteredNodes = [];
    let filteredOptsKeys = [];
    let expandedOptsKeys = [];
    let newFlattenNodes = [];
    let filteredShownKeys = new Set([]);
    if (!sugInput) {
      expandedOptsKeys = (0, _treeUtil.findAncestorKeys)(selectedKeys, keyEntities, false);
      expandedOptsKeys.forEach(item => newExpandedKeys.add(item));
      newFlattenNodes = (0, _treeUtil.flattenTreeData)(treeData, newExpandedKeys, keyMaps);
    } else {
      const filteredOpts = Object.values(keyEntities).filter(item => {
        const {
          data
        } = item;
        return (0, _treeUtil.filter)(sugInput, data, filterTreeNode, realFilterProp);
      });
      filteredNodes = filteredOpts.map(item => item.data);
      filteredOptsKeys = filteredOpts.map(item => item.key);
      expandedOptsKeys = (0, _treeUtil.findAncestorKeys)(filteredOptsKeys, keyEntities, false);
      const shownChildKeys = (0, _treeUtil.findDescendantKeys)(filteredOptsKeys, keyEntities, true);
      filteredShownKeys = new Set([...shownChildKeys, ...expandedOptsKeys]);
      newFlattenNodes = (0, _treeUtil.flattenTreeData)(treeData, new Set(expandedOptsKeys), keyMaps, showFilteredOnly && filteredShownKeys);
    }
    const newFilteredExpandedKeys = new Set(expandedOptsKeys);
    this._adapter.notifySearch(sugInput, Array.from(newFilteredExpandedKeys), filteredNodes);
    this._adapter.updateState({
      expandedKeys: newExpandedKeys,
      flattenNodes: newFlattenNodes,
      motionKeys: new Set([]),
      filteredKeys: new Set(filteredOptsKeys),
      filteredExpandedKeys: newFilteredExpandedKeys,
      filteredShownKeys
    });
    this._adapter.rePositionDropdown();
  }
  handleNodeSelect(e, treeNode) {
    const isDisabled = this._isDisabled(treeNode);
    if (isDisabled) {
      return;
    }
    if (!this._isMultiple()) {
      this.handleSingleSelect(e, treeNode);
    } else {
      this.handleMultipleSelect(e, treeNode);
    }
  }
  handleSingleSelect(e, treeNode) {
    let selectedKeys = [...this.getState('selectedKeys')];
    const {
      clickToHide
    } = this.getProps();
    const {
      selected,
      eventKey,
      data
    } = treeNode;
    this._adapter.notifySelect(eventKey, true, data);
    if (!selectedKeys.includes(eventKey) && !selected) {
      selectedKeys = [eventKey];
      this._notifyChange(eventKey, e);
      if (!this._isControlledComponent()) {
        this._adapter.updateState({
          selectedKeys
        });
      }
    }
    if (clickToHide && (this._isSelectToClose() || !data.children)) {
      this.close(e);
      this.handlerTriggerBlur(e);
    }
  }
  calcCheckedKeys(eventKey, targetStatus) {
    const {
      keyEntities
    } = this.getStates();
    const checkedKeys = new Set(this.getState('checkedKeys'));
    const halfCheckedKeys = new Set(this.getState('halfCheckedKeys'));
    if (targetStatus) {
      return (0, _treeUtil.calcCheckedKeysForChecked)(eventKey, keyEntities, checkedKeys, halfCheckedKeys);
    } else {
      return (0, _treeUtil.calcCheckedKeysForUnchecked)(eventKey, keyEntities, checkedKeys, halfCheckedKeys);
    }
  }
  handleMultipleSelect(e, treeNode) {
    const {
      searchPosition,
      disableStrictly,
      checkRelation
    } = this.getProps();
    const {
      inputValue,
      realCheckedKeys
    } = this.getStates();
    const {
      checked,
      eventKey,
      data
    } = treeNode;
    if (checkRelation === 'related') {
      const targetStatus = disableStrictly ? this.calcCheckedStatus(!checked, eventKey) : !checked;
      const {
        checkedKeys,
        halfCheckedKeys
      } = disableStrictly ? this.calcNonDisabledCheckedKeys(eventKey, targetStatus) : this.calcCheckedKeys(eventKey, targetStatus);
      this._adapter.notifySelect(eventKey, targetStatus, data);
      this._notifyChange([...checkedKeys], e);
      if (!this._isControlledComponent()) {
        this._adapter.updateState({
          checkedKeys,
          halfCheckedKeys
        });
        this._adapter.rePositionDropdown();
      }
    } else if (checkRelation === 'unRelated') {
      const newRealCheckedKeys = new Set(realCheckedKeys);
      let targetStatus;
      if (realCheckedKeys.has(eventKey)) {
        newRealCheckedKeys.delete(eventKey);
        targetStatus = false;
      } else {
        newRealCheckedKeys.add(eventKey);
        targetStatus = true;
      }
      this._adapter.notifySelect(eventKey, targetStatus, data);
      this._notifyChange([...newRealCheckedKeys], e);
      if (!this._isControlledComponent()) {
        this._adapter.updateState({
          realCheckedKeys: newRealCheckedKeys
        });
        this._adapter.rePositionDropdown();
      }
    }
    if (searchPosition === _constants.strings.SEARCH_POSITION_TRIGGER && inputValue !== '') {
      this._adapter.updateState({
        inputValue: ''
      });
    }
  }
  calcNonDisabledCheckedKeys(eventKey, targetStatus) {
    const {
      keyEntities,
      disabledKeys
    } = this.getStates();
    const checkedKeys = new Set(this.getState('checkedKeys'));
    const descendantKeys = (0, _treeUtil.normalizeKeyList)((0, _treeUtil.findDescendantKeys)([eventKey], keyEntities, false), keyEntities, true);
    const hasDisabled = descendantKeys.some(key => disabledKeys.has(key));
    if (!hasDisabled) {
      return this.calcCheckedKeys(eventKey, targetStatus);
    }
    const nonDisabled = descendantKeys.filter(key => !disabledKeys.has(key));
    const newCheckedKeys = targetStatus ? [...nonDisabled, ...checkedKeys] : (0, _difference2.default)((0, _treeUtil.normalizeKeyList)([...checkedKeys], keyEntities, true, true), nonDisabled);
    return (0, _treeUtil.calcCheckedKeys)(newCheckedKeys, keyEntities);
  }
  calcCheckedStatus(targetStatus, eventKey) {
    if (!targetStatus) {
      return targetStatus;
    }
    const {
      checkedKeys,
      keyEntities,
      disabledKeys
    } = this.getStates();
    const descendantKeys = (0, _treeUtil.normalizeKeyList)((0, _treeUtil.findDescendantKeys)([eventKey], keyEntities, false), keyEntities, true);
    const hasDisabled = descendantKeys.some(key => disabledKeys.has(key));
    if (!hasDisabled) {
      return targetStatus;
    }
    const nonDisabledKeys = descendantKeys.filter(key => !disabledKeys.has(key));
    const allChecked = nonDisabledKeys.every(key => checkedKeys.has(key));
    return !allChecked;
  }
  handleNodeExpandInSearch(e, treeNode) {
    const {
      treeData,
      filteredShownKeys,
      keyEntities,
      keyMaps
    } = this.getStates();
    const showFilteredOnly = this._showFilteredOnly();
    // clone otherwise will be modified unexpectedly
    const filteredExpandedKeys = new Set(this.getState('filteredExpandedKeys'));
    let motionType = 'show';
    const {
      eventKey,
      expanded,
      data
    } = treeNode;
    // debugger;
    if (!expanded) {
      filteredExpandedKeys.add(eventKey);
    } else if (filteredExpandedKeys.has(eventKey)) {
      filteredExpandedKeys.delete(eventKey);
      motionType = 'hide';
    }
    // cache prev flattenNodes, otherwise the calculation will remove hidden items
    this._adapter.cacheFlattenNodes(motionType === 'hide' && this._isAnimated());
    if (!this._isExpandControlled()) {
      // debugger;
      const flattenNodes = (0, _treeUtil.flattenTreeData)(treeData, filteredExpandedKeys, keyMaps, showFilteredOnly && filteredShownKeys);
      const motionKeys = this._isAnimated() ? (0, _treeUtil.getMotionKeys)(eventKey, filteredExpandedKeys, keyEntities) : [];
      const newState = {
        filteredExpandedKeys,
        flattenNodes,
        motionKeys: new Set(motionKeys),
        motionType
      };
      this._adapter.updateState(newState);
    }
    this._adapter.notifyExpand(filteredExpandedKeys, {
      expanded: !expanded,
      node: data
    });
  }
  handleNodeExpand(e, treeNode) {
    // debugger;
    const {
      loadData,
      keyMaps
    } = this.getProps();
    const {
      inputValue,
      keyEntities
    } = this.getStates();
    const isSearching = Boolean(inputValue);
    if (!loadData && (!treeNode.children || !treeNode.children.length)) {
      return;
    }
    const isExpandControlled = this._isExpandControlled();
    if (isSearching) {
      this.handleNodeExpandInSearch(e, treeNode);
      return;
    }
    const {
      treeData
    } = this.getStates();
    // clone otherwise will be modified unexpectedly
    const expandedKeys = new Set(this.getState('expandedKeys'));
    let motionType = 'show';
    const {
      eventKey,
      expanded,
      data
    } = treeNode;
    if (!expanded) {
      expandedKeys.add(eventKey);
    } else if (expandedKeys.has(eventKey)) {
      expandedKeys.delete(eventKey);
      motionType = 'hide';
    }
    this._adapter.cacheFlattenNodes(motionType === 'hide' && this._isAnimated());
    if (!isExpandControlled) {
      // debugger;
      const flattenNodes = (0, _treeUtil.flattenTreeData)(treeData, expandedKeys, keyMaps);
      const motionKeys = this._isAnimated() ? (0, _treeUtil.getMotionKeys)(eventKey, expandedKeys, keyEntities) : [];
      const newState = {
        expandedKeys,
        flattenNodes,
        motionKeys: new Set(motionKeys),
        motionType
      };
      this._adapter.updateState(newState);
    }
    this._adapter.notifyExpand(expandedKeys, {
      expanded: !expanded,
      node: data
    });
  }
  /**
   * The selected items that need to be displayed in the search box when obtaining a single selection
   */
  getRenderTextInSingle() {
    const {
      renderSelectedItem: propRenderSelectedItem,
      treeNodeLabelProp,
      keyMaps
    } = this.getProps();
    const {
      selectedKeys,
      keyEntities
    } = this.getStates();
    const realLabelName = (0, _get2.default)(keyMaps, 'label', treeNodeLabelProp);
    const renderSelectedItem = (0, _isFunction2.default)(propRenderSelectedItem) ? propRenderSelectedItem : item => (0, _get2.default)(item, realLabelName, null);
    let item;
    if (selectedKeys.length) {
      const key = selectedKeys[0];
      item = keyEntities[key] && keyEntities[key].key === key ? keyEntities[key].data : this.getDataForKeyNotInKeyEntities(key);
    }
    const renderText = item ? renderSelectedItem(item) : null;
    return renderText;
  }
  /**
   * When the search box is on the trigger, the blur event handling method
   */
  handleInputTriggerBlur() {
    this._adapter.updateState({
      inputTriggerFocus: false
    });
  }
  /**
   * When the search box is on the trigger, the focus event processing method
   */
  handleInputTriggerFocus() {
    this.clearInput();
    this._adapter.updateState({
      inputTriggerFocus: true
    });
  }
  setLoadKeys(data, resolve) {
    this._adapter.updateLoadKeys(data, resolve);
  }
  handlePopoverVisibleChange(isVisible) {
    const {
      filterTreeNode,
      searchAutoFocus,
      searchPosition
    } = this.getProps();
    // 将 inputValue 清空，如果有选中值的话，选中项能够快速回显
    // Clear the inputValue. If there is a selected value, the selected item can be quickly echoed.
    if (isVisible === false && filterTreeNode) {
      this.clearInputValue();
    }
    if (filterTreeNode && searchPosition === _constants.strings.SEARCH_POSITION_DROPDOWN && isVisible && searchAutoFocus) {
      this.focusInput(true);
    }
  }
  handleAfterClose() {
    // flattenNode 的变化将导致弹出层面板中的选项数目变化
    // 在弹层完全收起之后，再通过 clearInput 重新计算 state 中的 expandedKey， flattenNode
    // 防止在弹出层未收起时弹层面板中选项数目变化导致视觉上出现弹层闪动问题
    // Changes to flattenNode will cause the number of options in the popup panel to change
    // After the pop-up layer is completely closed, recalculate the expandedKey and flattenNode in the state through clearInput.
    // Prevent the pop-up layer from flickering visually due to changes in the number of options in the pop-up panel when the pop-up layer is not collapsed.
    const {
      filterTreeNode
    } = this.getProps();
    filterTreeNode && this.clearInput();
  }
}
exports.default = TreeSelectFoundation;