/**
 * ldesign v0.4.2
 * (c) 2023 ldesign
 * @license MIT
 */

'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var _classCallCheck = require('@babel/runtime/helpers/classCallCheck');
var _createClass = require('@babel/runtime/helpers/createClass');
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
var isArray = require('lodash/isArray');
var isFunction = require('lodash/isFunction');
var isNumber = require('lodash/isNumber');
var isString = require('lodash/isString');
var difference = require('lodash/difference');
var camelCase = require('lodash/camelCase');
var isPlainObject = require('lodash/isPlainObject');
var mitt = require('mitt');
var _common_js_tree_treeNode = require('./tree-node.js');
require('@babel/runtime/helpers/asyncToGenerator');
require('@babel/runtime/helpers/toConsumableArray');
require('@babel/runtime/regenerator');
require('lodash/isNull');
require('lodash/uniqueId');
require('lodash/isNil');
require('lodash/get');
require('../log/log.js');
require('./tree-node-model.js');
require('lodash/isUndefined');
require('lodash/isBoolean');
require('lodash/pick');
require('lodash/omit');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var _classCallCheck__default = /*#__PURE__*/_interopDefaultLegacy(_classCallCheck);
var _createClass__default = /*#__PURE__*/_interopDefaultLegacy(_createClass);
var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
var isArray__default = /*#__PURE__*/_interopDefaultLegacy(isArray);
var isFunction__default = /*#__PURE__*/_interopDefaultLegacy(isFunction);
var isNumber__default = /*#__PURE__*/_interopDefaultLegacy(isNumber);
var isString__default = /*#__PURE__*/_interopDefaultLegacy(isString);
var difference__default = /*#__PURE__*/_interopDefaultLegacy(difference);
var camelCase__default = /*#__PURE__*/_interopDefaultLegacy(camelCase);
var isPlainObject__default = /*#__PURE__*/_interopDefaultLegacy(isPlainObject);
var mitt__default = /*#__PURE__*/_interopDefaultLegacy(mitt);

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__default["default"](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__default["default"](this, TreeStore);
    _defineProperty__default["default"](this, "children", void 0);
    _defineProperty__default["default"](this, "nodes", void 0);
    _defineProperty__default["default"](this, "nodeMap", void 0);
    _defineProperty__default["default"](this, "privateMap", void 0);
    _defineProperty__default["default"](this, "config", void 0);
    _defineProperty__default["default"](this, "activedMap", void 0);
    _defineProperty__default["default"](this, "updatedMap", void 0);
    _defineProperty__default["default"](this, "checkedMap", void 0);
    _defineProperty__default["default"](this, "expandedMap", void 0);
    _defineProperty__default["default"](this, "filterMap", void 0);
    _defineProperty__default["default"](this, "updateTimer", void 0);
    _defineProperty__default["default"](this, "shouldReflow", void 0);
    _defineProperty__default["default"](this, "hasFilter", void 0);
    _defineProperty__default["default"](this, "prevFilter", void 0);
    _defineProperty__default["default"](this, "emitter", 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,
      draggable: 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.privateMap = /* @__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;
    this.hasFilter = isFunction__default["default"](config.filter);
    this.emitter = mitt__default["default"]();
  }
  _createClass__default["default"](TreeStore, [{
    key: "setConfig",
    value: function setConfig(options) {
      var config = this.config;
      var hasChanged = false;
      Object.keys(options).forEach(function (key) {
        var val = options[key];
        if (val !== config[key]) {
          hasChanged = true;
          config[key] = val;
        }
      });
      this.hasFilter = isFunction__default["default"](config.filter);
      if (hasChanged) {
        this.refreshState();
      }
    }
  }, {
    key: "getChildren",
    value: function getChildren() {
      return this.children;
    }
  }, {
    key: "getNode",
    value: function getNode(item) {
      var node = null;
      if (isString__default["default"](item) || isNumber__default["default"](item)) node = this.nodeMap.get(item);else if (item instanceof _common_js_tree_treeNode.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 (isString__default["default"](item) || isNumber__default["default"](item)) val = item;else if (item instanceof _common_js_tree_treeNode.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 (isNumber__default["default"](conf.level) && conf.level !== Infinity) nodes = nodes.filter(function (node) {
          return node.level <= conf.level;
        });
        if (isFunction__default["default"](conf.filter)) {
          nodes = nodes.filter(function (node) {
            var nodeModel = node.getModel();
            return conf.filter(nodeModel);
          });
        }
        if (isPlainObject__default["default"](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 _this = this;
      list.forEach(function (item) {
        var node = new _common_js_tree_treeNode.TreeNode(_this, item);
        _this.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 (isString__default["default"](para) || isNumber__default["default"](para)) {
        value = para;
        data = item;
        node = this.getNode(value);
      } else if (para instanceof _common_js_tree_treeNode.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 _common_js_tree_treeNode.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 _common_js_tree_treeNode.TreeNode) spec.data.appendTo(this, spec.node);else if (isArray__default["default"](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 _this2 = this;
      if (node !== null && node !== void 0 && node.value) this.updatedMap.set(node.value, true);
      if (this.updateTimer) return;
      this.updateTimer = setTimeout(function () {
        clearTimeout(_this2.updateTimer);
        _this2.updateTimer = null;
        if (_this2.shouldReflow) {
          _this2.refreshNodes();
          _this2.emit("reflow");
        }
        _this2.lockFilterPathNodes();
        var updatedList = Array.from(_this2.updatedMap.keys());
        if (updatedList.length > 0) {
          var updatedNodes = updatedList.map(function (value) {
            return _this2.getNode(value);
          });
          _this2.emit("update", {
            nodes: updatedNodes,
            map: _this2.updatedMap
          });
        } else if (_this2.shouldReflow) {
          _this2.emit("update", {
            nodes: [],
            map: _this2.updatedMap
          });
        }
        _this2.shouldReflow = false;
        _this2.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 _this3 = this;
      var activeMultiple = this.config.activeMultiple;
      var list = actived.slice(0);
      if (!activeMultiple) list.length = 1;
      list.forEach(function (val) {
        _this3.activedMap.set(val, true);
        var node = _this3.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__default["default"](list, expanded);
      var removed = difference__default["default"](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 _this4 = this;
      var expanded = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      list.forEach(function (val) {
        if (expanded) {
          _this4.expandedMap.set(val, true);
          var node = _this4.getNode(val);
          if (node) node.afterExpanded();
        } else {
          _this4.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, true);
    }
  }, {
    key: "setChecked",
    value: function setChecked(list, isFromValueChange) {
      var _this5 = 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 = _this5.getNode(val);
        if (node) {
          if (valueMode === "parentFirst" && !checkStrictly) {
            var childrenNodes = node.walk();
            childrenNodes.forEach(function (childNode) {
              _this5.checkedMap.set(childNode.value, true);
            });
          } else {
            _this5.checkedMap.set(val, true);
            node.updateChecked(isFromValueChange);
          }
        }
      });
      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 _this6 = this;
      var conf = _objectSpread({
        withParents: true
      }, options);
      var map = /* @__PURE__ */new Map();
      list.forEach(function (value) {
        if (map.get(value)) return;
        var node = _this6.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,
        emitter = this.emitter;
      var methodName = camelCase__default["default"]("on-".concat(name));
      var method = config[methodName];
      if (isFunction__default["default"](method)) method(state);
      emitter.emit(name, state);
    }
  }, {
    key: "lockFilterPathNodes",
    value: function lockFilterPathNodes() {
      var config = this.config;
      var allNodes = this.getNodes();
      if (this.prevFilter) {
        allNodes.forEach(function (node) {
          if (node.vmIsLocked) {
            node.lock(false);
          }
        });
      }
      var currentFilter = config.filter;
      if (!currentFilter || !isFunction__default["default"](currentFilter)) return;
      this.prevFilter = config.filter;
      allNodes.reverse().forEach(function (node) {
        var parent = node.getParent();
        if (!parent) return;
        if (node.vmIsRest || node.vmIsLocked) {
          if (!parent.vmIsLocked) {
            parent.lock(true);
          }
        }
      });
    }
  }]);
  return TreeStore;
}();

exports.TreeStore = TreeStore;
exports["default"] = TreeStore;
//# sourceMappingURL=tree-store.js.map
