/**
 * tdesign v0.39.1-alpha.1
 * (c) 2022 tdesign
 * @license MIT
 */

import _classCallCheck from '@babel/runtime/helpers/classCallCheck';
import _createClass from '@babel/runtime/helpers/createClass';
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import difference from 'lodash/difference';
import camelCase from 'lodash/camelCase';
import isPlainObject from 'lodash/isPlainObject';
import { TreeNode } from './tree-node.js';
import '@babel/runtime/helpers/asyncToGenerator';
import '@babel/runtime/helpers/toConsumableArray';
import '@babel/runtime/regenerator';
import 'lodash/uniqueId';
import 'lodash/get';
import './tree-node-model.js';
import 'lodash/pick';
import '../log/log.js';

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
var TreeStore = /*#__PURE__*/function () {
  function TreeStore(options) {
    _classCallCheck(this, TreeStore);

    _defineProperty(this, "children", void 0);

    _defineProperty(this, "nodes", void 0);

    _defineProperty(this, "nodeMap", void 0);

    _defineProperty(this, "config", void 0);

    _defineProperty(this, "activedMap", void 0);

    _defineProperty(this, "updatedMap", void 0);

    _defineProperty(this, "checkedMap", void 0);

    _defineProperty(this, "expandedMap", void 0);

    _defineProperty(this, "filterMap", void 0);

    _defineProperty(this, "updateTimer", void 0);

    _defineProperty(this, "shouldReflow", void 0);

    _defineProperty(this, "prevFilter", void 0);

    var config = _objectSpread({
      prefix: "t",
      keys: {},
      expandAll: false,
      expandLevel: 0,
      expandMutex: false,
      expandParent: false,
      activable: false,
      activeMultiple: false,
      checkable: false,
      checkStrictly: false,
      disabled: false,
      load: null,
      lazy: false,
      valueMode: "onlyLeaf",
      filter: null,
      onLoad: null,
      onReflow: null,
      onUpdate: null,
      allowFoldNodeOnFilter: false
    }, options);

    this.config = config;
    this.nodes = [];
    this.children = [];
    this.nodeMap = /* @__PURE__ */new Map();
    this.activedMap = /* @__PURE__ */new Map();
    this.expandedMap = /* @__PURE__ */new Map();
    this.checkedMap = /* @__PURE__ */new Map();
    this.updatedMap = /* @__PURE__ */new Map();
    this.filterMap = /* @__PURE__ */new Map();
    this.prevFilter = null;
    this.updateTimer = null;
    this.shouldReflow = false;
  }

  _createClass(TreeStore, [{
    key: "setConfig",
    value: function setConfig(options) {
      var _this = this;

      var hasChanged = false;
      Object.keys(options).forEach(function (key) {
        var val = options[key];

        if (val !== _this.config[key]) {
          hasChanged = true;
          _this.config[key] = val;
        }
      });

      if (hasChanged) {
        this.refreshState();
      }
    }
  }, {
    key: "getChildren",
    value: function getChildren() {
      return this.children;
    }
  }, {
    key: "getNode",
    value: function getNode(item) {
      var node = null;

      if (typeof item === "string" || typeof item === "number") {
        node = this.nodeMap.get(item);
      } else if (item instanceof TreeNode) {
        node = this.nodeMap.get(item.value);
      }

      return node;
    }
  }, {
    key: "getIndex",
    value: function getIndex(node) {
      return this.nodes.indexOf(node);
    }
  }, {
    key: "getParent",
    value: function getParent(value) {
      var parent = null;
      var node = this.getNode(value);

      if (node) {
        parent = node.getParent();
      }

      return parent;
    }
  }, {
    key: "getParents",
    value: function getParents(value) {
      var node = this.getNode(value);
      var parents = [];

      if (node) {
        parents = node.getParents();
      }

      return parents;
    }
  }, {
    key: "getNodeIndex",
    value: function getNodeIndex(value) {
      var node = this.getNode(value);
      var index = -1;

      if (node) {
        index = node.getIndex();
      }

      return index;
    }
  }, {
    key: "getNodes",
    value: function getNodes(item, options) {
      var nodes = [];
      var val = "";

      if (typeof item === "string" || typeof item === "number") {
        val = item;
      } else if (item instanceof TreeNode) {
        val = item.value;
      }

      if (!val) {
        nodes = this.nodes.slice(0);
      } else {
        var node = this.getNode(val);

        if (node) {
          nodes = node.walk();
        }
      }

      if (options) {
        var conf = _objectSpread({
          filter: null,
          level: Infinity
        }, options);

        if (typeof conf.level === "number" && conf.level !== Infinity) {
          nodes = nodes.filter(function (node) {
            return node.level <= conf.level;
          });
        }

        if (typeof conf.filter === "function") {
          nodes = nodes.filter(function (node) {
            var nodeModel = node.getModel();
            return conf.filter(nodeModel);
          });
        }

        if (isPlainObject(conf.props)) {
          nodes = nodes.filter(function (node) {
            var result = Object.keys(conf.props).every(function (key) {
              var propEqual = node[key] === conf.props[key];
              return propEqual;
            });
            return result;
          });
        }
      }

      return nodes;
    }
  }, {
    key: "append",
    value: function append(list) {
      var _this2 = this;

      list.forEach(function (item) {
        var node = new TreeNode(_this2, item);

        _this2.children.push(node);
      });
      this.reflow();
    }
  }, {
    key: "reload",
    value: function reload(list) {
      this.expandedMap.clear();
      this.checkedMap.clear();
      this.activedMap.clear();
      this.filterMap.clear();
      this.removeAll();
      this.append(list);
    }
  }, {
    key: "parseNodeData",
    value: function parseNodeData(para, item) {
      var value = "";
      var node = null;
      var data = null;

      if (typeof para === "string" || typeof para === "number") {
        value = para;
        data = item;
        node = this.getNode(value);
      } else if (para instanceof TreeNode) {
        node = para;
        data = item;
      } else {
        data = para;
      }

      var spec = {
        node: node,
        data: data
      };
      return spec;
    }
  }, {
    key: "appendNodes",
    value: function appendNodes(para, item) {
      var spec = this.parseNodeData(para, item);

      if (spec.data) {
        if (!spec.node) {
          if (spec.data instanceof TreeNode) {
            spec.data.appendTo(this);
          } else if (Array.isArray(spec.data)) {
            this.append(spec.data);
          } else {
            this.append([spec.data]);
          }
        } else {
          if (spec.data instanceof TreeNode) {
            spec.data.appendTo(this, spec.node);
          } else if (Array.isArray(spec.data)) {
            spec.node.append(spec.data);
          } else {
            spec.node.append([spec.data]);
          }

          spec.node.updateRelated();
        }
      }
    }
  }, {
    key: "insertBefore",
    value: function insertBefore(value, item) {
      var node = this.getNode(value);

      if (node) {
        node.insertBefore(item);
      }
    }
  }, {
    key: "insertAfter",
    value: function insertAfter(value, item) {
      var node = this.getNode(value);

      if (node) {
        node.insertAfter(item);
      }
    }
  }, {
    key: "refreshNodes",
    value: function refreshNodes() {
      var children = this.children,
          nodes = this.nodes;
      nodes.length = 0;
      children.forEach(function (node) {
        var list = node.walk();
        Array.prototype.push.apply(nodes, list);
      });
    }
  }, {
    key: "refreshState",
    value: function refreshState() {
      var nodes = this.nodes;
      nodes.forEach(function (node) {
        node.update();
        node.updateChecked();
      });
    }
  }, {
    key: "reflow",
    value: function reflow(node) {
      this.shouldReflow = true;
      this.updated(node);
    }
  }, {
    key: "updated",
    value: function updated(node) {
      var _this3 = this;

      if (node !== null && node !== void 0 && node.value) {
        this.updatedMap.set(node.value, true);
      }

      if (this.updateTimer) return;
      this.updateTimer = +setTimeout(function () {
        var _this3$config;

        clearTimeout(_this3.updateTimer);
        _this3.updateTimer = null;

        if (_this3.shouldReflow) {
          _this3.refreshNodes();

          _this3.emit("reflow");
        }

        if (!((_this3$config = _this3.config) !== null && _this3$config !== void 0 && _this3$config.allowFoldNodeOnFilter)) _this3.lockFilterPathNodes();
        var updatedList = Array.from(_this3.updatedMap.keys());

        if (updatedList.length > 0) {
          var updatedNodes = updatedList.map(function (value) {
            return _this3.getNode(value);
          });

          _this3.emit("update", {
            nodes: updatedNodes,
            map: _this3.updatedMap
          });
        } else if (_this3.shouldReflow) {
          _this3.emit("update", {
            nodes: [],
            map: _this3.updatedMap
          });
        }

        _this3.shouldReflow = false;

        _this3.updatedMap.clear();
      });
    }
  }, {
    key: "getActived",
    value: function getActived(map) {
      var activedMap = map || this.activedMap;
      return Array.from(activedMap.keys());
    }
  }, {
    key: "getActivedNodes",
    value: function getActivedNodes(item) {
      var nodes = this.getNodes(item);
      nodes = nodes.filter(function (node) {
        return node.isActived();
      });
      return nodes;
    }
  }, {
    key: "replaceActived",
    value: function replaceActived(list) {
      this.resetActived();
      this.setActived(list);
    }
  }, {
    key: "setActived",
    value: function setActived(actived) {
      var _this4 = this;

      var activeMultiple = this.config.activeMultiple;
      var list = actived.slice(0);

      if (!activeMultiple) {
        list.length = 1;
      }

      list.forEach(function (val) {
        _this4.activedMap.set(val, true);

        var node = _this4.getNode(val);

        if (node) {
          node.update();
        }
      });
    }
  }, {
    key: "resetActived",
    value: function resetActived() {
      var actived = this.getActived();
      this.activedMap.clear();
      var relatedNodes = this.getRelatedNodes(actived);
      relatedNodes.forEach(function (node) {
        node.update();
      });
    }
  }, {
    key: "getExpanded",
    value: function getExpanded(map) {
      var expandedMap = map || this.expandedMap;
      return Array.from(expandedMap.keys());
    }
  }, {
    key: "replaceExpanded",
    value: function replaceExpanded(list) {
      var expanded = this.getExpanded();
      var added = difference(list, expanded);
      var removed = difference(expanded, list);
      this.setExpandedDirectly(removed, false);
      this.updateExpanded(removed);
      this.setExpanded(added);
    }
  }, {
    key: "setExpanded",
    value: function setExpanded(list) {
      this.setExpandedDirectly(list);
      this.updateExpanded(list);
    }
  }, {
    key: "setExpandedDirectly",
    value: function setExpandedDirectly(list) {
      var _this5 = this;

      var expanded = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      list.forEach(function (val) {
        if (expanded) {
          _this5.expandedMap.set(val, true);

          var node = _this5.getNode(val);

          if (node) {
            node.afterExpanded();
          }
        } else {
          _this5.expandedMap["delete"](val);
        }
      });
    }
  }, {
    key: "resetExpanded",
    value: function resetExpanded() {
      var expanded = this.getExpanded();
      this.expandedMap.clear();
      this.updateExpanded(expanded);
    }
  }, {
    key: "updateExpanded",
    value: function updateExpanded(list) {
      var relatedNodes = this.getRelatedNodes(list, {
        withParents: false
      });
      relatedNodes.forEach(function (node) {
        node.update();
      });
    }
  }, {
    key: "getChecked",
    value: function getChecked(map) {
      var nodes = this.nodes,
          config = this.config;
      var valueMode = config.valueMode,
          checkStrictly = config.checkStrictly;
      var list = [];
      var checkedMap = map || this.checkedMap;
      nodes.forEach(function (node) {
        if (node.isChecked(checkedMap)) {
          if (valueMode === "parentFirst" && !checkStrictly) {
            if (!node.parent || !node.parent.isChecked(checkedMap)) {
              list.push(node.value);
            }
          } else if (valueMode === "onlyLeaf" && !checkStrictly) {
            if (node.isLeaf()) {
              list.push(node.value);
            }
          } else {
            list.push(node.value);
          }
        }
      });
      return list;
    }
  }, {
    key: "getCheckedNodes",
    value: function getCheckedNodes(item) {
      var nodes = this.getNodes(item);
      nodes = nodes.filter(function (node) {
        return node.isChecked();
      });
      return nodes;
    }
  }, {
    key: "replaceChecked",
    value: function replaceChecked(list) {
      this.resetChecked();
      this.setChecked(list);
    }
  }, {
    key: "setChecked",
    value: function setChecked(list) {
      var _this6 = this;

      var _this$config = this.config,
          valueMode = _this$config.valueMode,
          checkStrictly = _this$config.checkStrictly,
          checkable = _this$config.checkable;
      if (!checkable) return;
      list.forEach(function (val) {
        var node = _this6.getNode(val);

        if (node) {
          if (valueMode === "parentFirst" && !checkStrictly) {
            var childrenNodes = node.walk();
            childrenNodes.forEach(function (childNode) {
              _this6.checkedMap.set(childNode.value, true);
            });
          } else {
            _this6.checkedMap.set(val, true);

            node.updateChecked();
          }
        }
      });

      if (!checkStrictly) {
        var checked = this.getChecked();
        var relatedNodes = this.getRelatedNodes(checked);
        relatedNodes.forEach(function (node) {
          node.updateChecked();
        });
      }
    }
  }, {
    key: "resetChecked",
    value: function resetChecked() {
      var checked = this.getChecked();
      var relatedNodes = this.getRelatedNodes(checked);
      this.checkedMap.clear();
      relatedNodes.forEach(function (node) {
        node.updateChecked();
      });
    }
  }, {
    key: "updateAll",
    value: function updateAll() {
      var nodes = this.getNodes();
      nodes.forEach(function (node) {
        node.update();
      });
    }
  }, {
    key: "remove",
    value: function remove(value) {
      var node = this.getNode(value);

      if (node) {
        node.remove();
      }
    }
  }, {
    key: "removeAll",
    value: function removeAll() {
      var nodes = this.getNodes();
      nodes.forEach(function (node) {
        node.remove();
      });
    }
  }, {
    key: "getRelatedNodes",
    value: function getRelatedNodes(list, options) {
      var _this7 = this;

      var conf = _objectSpread({
        withParents: true
      }, options);

      var map = /* @__PURE__ */new Map();
      list.forEach(function (value) {
        if (map.get(value)) return;

        var node = _this7.getNode(value);

        if (node) {
          var parents = node.getParents();
          var children = node.walk();
          var related = [];

          if (conf.withParents) {
            related = parents.concat(children);
          } else {
            related = children;
          }

          related.forEach(function (relatedNode) {
            map.set(relatedNode.value, relatedNode);
          });
        }
      });
      var relatedNodes = Array.from(map.values());
      return relatedNodes;
    }
  }, {
    key: "emit",
    value: function emit(name, state) {
      var config = this.config || {};
      var methodName = camelCase("on-".concat(name));
      var method = config[methodName];

      if (typeof method === "function") {
        method(state);
      }
    }
  }, {
    key: "lockFilterPathNodes",
    value: function lockFilterPathNodes() {
      var _this8 = this;

      var config = this.config;
      var allNodes = this.getNodes();

      if (this.prevFilter) {
        allNodes.forEach(function (node) {
          node.lock(false);
        });
      }

      if (!config.filter) {
        return;
      }

      this.prevFilter = config.filter;
      var map = /* @__PURE__ */new Map();
      allNodes.reverse().forEach(function (item) {
        var node = item;
        var parent = node.getParent();

        if (node.vmIsRest) {
          if (parent) {
            parent.expanded = true;
          }

          node.visible = true;
        }

        if (node.vmIsRest || map.get(node.value)) {
          if (parent && !parent.vmIsRest) {
            map.set(parent.value, true);
          }
        }
      });
      var filterPathValues = Array.from(map.keys());
      filterPathValues.forEach(function (value) {
        var node = _this8.getNode(value);

        if (node) {
          node.lock(true);
        }
      });
    }
  }]);

  return TreeStore;
}();

export { TreeStore, TreeStore as default };
//# sourceMappingURL=tree-store.js.map
