import "choerodon-ui/pro/lib/tree/style";
import _Tree from "choerodon-ui/pro/lib/tree";

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }

function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }

function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }

function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }

function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

import React, { Fragment, useMemo, useCallback } from 'react';
import { observer } from 'mobx-react-lite';
import { runInAction } from 'mobx';
import toUpper from 'lodash/toUpper';
import { uniqBy } from 'lodash';
import classnames from 'classnames';
import ScrollArea from "../scroll-area";
import TreeSearch from "./tree-search";
import "./index.less";
/**
 * 展开节点的所有父节点
 * 通过Record内置的方法展开目标节点
 * 将展开节点缓存进传入的数组
 * @param record
 * @param expendedKeys
 */

function expandParents(record, expendedKeys) {
  if (!record.isExpanded) {
    var children = record.children;

    if (children && children.length) {
      var key = record.get('key');
      expendedKeys.push(key); // eslint-disable-next-line no-param-reassign

      record.isExpanded = true;
    }

    var parent = record.parent;

    if (parent && !parent.isExpanded) {
      expandParents(parent, expendedKeys);
    }
  }
}
/**
 * 获取子节点
 */


function getChildren(record, childrenRecords) {
  var children = record.children;

  if (children && children.length) {
    childrenRecords.push.apply(childrenRecords, _toConsumableArray(children));
    children.forEach(function (childrenRecord) {
      return getChildren(childrenRecord, childrenRecords);
    });
  }
}
/**
 * 获取父节点
 */


function getParent(record, parentRecords) {
  var parent = record.parent;

  if (parent) {
    parentRecords.push(parent);
    getParent(parent, parentRecords);
  }
}

var TreeView = observer(function (_ref) {
  var ds = _ref.ds,
      store = _ref.store,
      nodesRender = _ref.nodesRender,
      searchAble = _ref.searchAble,
      isFilter = _ref.isFilter,
      otherTreeProps = _ref.otherTreeProps,
      onSearch = _ref.onSearch;
  var treeClass = useMemo(function () {
    return classnames({
      'c7ncd-menu-wrap': true,
      'c7ncd-menu-scroll': searchAble
    });
  }, [searchAble]);
  var nodeRenderer = useCallback(function (_ref2) {
    var record = _ref2.record;
    return nodesRender(record, store.getSearchValue);
  }, [store.getSearchValue]);

  function handleSearch(_x) {
    return _handleSearch.apply(this, arguments);
  }

  function _handleSearch() {
    _handleSearch = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(value) {
      var realValue, expandedKeys, searchRecords, uniqKeys;
      return regeneratorRuntime.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              realValue = value || '';
              expandedKeys = [];
              searchRecords = [];

              if (!isFilter) {
                _context.next = 11;
                break;
              }

              if (!(value && store.getSearchValue && value !== store.getSearchValue)) {
                _context.next = 7;
                break;
              }

              _context.next = 7;
              return ds.query();

            case 7:
              store.setSearchValue(realValue);

              if (value) {
                _context.next = 11;
                break;
              }

              ds.query();
              return _context.abrupt("return");

            case 11:
              // NOTE: 让多个 action 只执行一次
              runInAction(function () {
                /**
                 *
                 * 如果在 DataSet 的 load 方法中对原始数据进行了修改
                 * 那么就不能使用 ds.reset(); 进行重置，因为该方法是基于 originalData 的
                 * 应该手动将各记录重置
                 *
                 * */
                ds.forEach(function (record) {
                  record.reset();
                  /**
                   * 未清除搜索值就刷新，Record会记录expand状态，导致上一步record.reset()失效
                   * */
                  // eslint-disable-next-line no-param-reassign

                  record.isExpanded = false;
                });
                ds.forEach(function (record) {
                  var name = record.get('name');

                  if (value && toUpper(name).indexOf(toUpper(value)) > -1) {
                    expandParents(record, expandedKeys);

                    if (isFilter) {
                      var childrenRecords = [];
                      var parentRecords = [];
                      getChildren(record, childrenRecords);
                      getParent(record, parentRecords);
                      searchRecords.push.apply(searchRecords, [record].concat(parentRecords, childrenRecords));
                    }
                  }
                });

                if (isFilter) {
                  var uniqKeys = new Set(expandedKeys);
                  var newSearchRecords = uniqBy(searchRecords, 'id');
                  handleExpanded(_toConsumableArray(uniqKeys));
                  ds.loadData(newSearchRecords.map(function (eachRecord) {
                    return eachRecord.toData();
                  }));
                }
              });

              if (!isFilter) {
                uniqKeys = new Set(expandedKeys);
                store.setSearchValue(realValue);
                handleExpanded(_toConsumableArray(uniqKeys));
              }

            case 13:
            case "end":
              return _context.stop();
          }
        }
      }, _callee);
    }));
    return _handleSearch.apply(this, arguments);
  }

  function handleExpanded(keys) {
    store.setExpandedKeys(keys);
  }

  return /*#__PURE__*/React.createElement(React.Fragment, null, searchAble && /*#__PURE__*/React.createElement(TreeSearch, {
    value: store.getSearchValue,
    onChange: onSearch || handleSearch
  }), /*#__PURE__*/React.createElement(ScrollArea, {
    vertical: true,
    className: treeClass
  }, /*#__PURE__*/React.createElement(_Tree, Object.assign({
    className: "c7ncd-menu",
    onExpand: handleExpanded,
    dataSet: ds,
    renderer: nodeRenderer
  }, otherTreeProps)), store.getSearchValue && !ds.length && /*#__PURE__*/React.createElement("span", {
    className: "c7ncd-menu-search-empty"
  }, "\u6682\u65E0\u6570\u636E")));
});
TreeView.defaultProps = {
  searchAble: true,
  isFilter: false,
  otherTreeProps: {}
};
export default TreeView;