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

'use strict';

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

var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator');
var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
var _classCallCheck = require('@babel/runtime/helpers/classCallCheck');
var _createClass = require('@babel/runtime/helpers/createClass');
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
var _regeneratorRuntime = require('@babel/runtime/regenerator');
var uniqueId = require('lodash/uniqueId');
var get = require('lodash/get');
var _common_js_tree_treeNodeModel = require('./tree-node-model.js');
require('lodash/pick');
require('../log/log.js');

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

var _asyncToGenerator__default = /*#__PURE__*/_interopDefaultLegacy(_asyncToGenerator);
var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray);
var _classCallCheck__default = /*#__PURE__*/_interopDefaultLegacy(_classCallCheck);
var _createClass__default = /*#__PURE__*/_interopDefaultLegacy(_createClass);
var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
var _regeneratorRuntime__default = /*#__PURE__*/_interopDefaultLegacy(_regeneratorRuntime);
var uniqueId__default = /*#__PURE__*/_interopDefaultLegacy(uniqueId);
var get__default = /*#__PURE__*/_interopDefaultLegacy(get);

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 hasOwnProperty = Object.prototype.hasOwnProperty;
var defaultStatus = {
  expandMutex: false,
  activable: false,
  checkable: false,
  disabled: false,
  draggable: false,
  loading: false
};
var TreeNode = /*#__PURE__*/function () {
  function TreeNode(tree, data, parent) {
    _classCallCheck__default["default"](this, TreeNode);

    _defineProperty__default["default"](this, "tree", void 0);

    _defineProperty__default["default"](this, "value", void 0);

    _defineProperty__default["default"](this, "label", void 0);

    _defineProperty__default["default"](this, "data", void 0);

    _defineProperty__default["default"](this, "parent", void 0);

    _defineProperty__default["default"](this, "children", void 0);

    _defineProperty__default["default"](this, "model", void 0);

    _defineProperty__default["default"](this, "vmIsLeaf", void 0);

    _defineProperty__default["default"](this, "vmIsFirst", void 0);

    _defineProperty__default["default"](this, "vmIsLast", void 0);

    _defineProperty__default["default"](this, "vmIsRest", void 0);

    _defineProperty__default["default"](this, "vmIsLocked", void 0);

    _defineProperty__default["default"](this, "expanded", void 0);

    _defineProperty__default["default"](this, "expandMutex", void 0);

    _defineProperty__default["default"](this, "actived", void 0);

    _defineProperty__default["default"](this, "activable", void 0);

    _defineProperty__default["default"](this, "checkable", void 0);

    _defineProperty__default["default"](this, "vmCheckable", void 0);

    _defineProperty__default["default"](this, "checked", void 0);

    _defineProperty__default["default"](this, "indeterminate", void 0);

    _defineProperty__default["default"](this, "disabled", void 0);

    _defineProperty__default["default"](this, "draggable", void 0);

    _defineProperty__default["default"](this, "visible", void 0);

    _defineProperty__default["default"](this, "level", void 0);

    _defineProperty__default["default"](this, "loading", void 0);

    this.data = data;
    this.tree = tree;
    var config = tree.config || {};
    var prefix = config.prefix || "t";
    var keys = get__default["default"](tree, "config.keys") || {};
    var propChildren = keys.children || "children";
    var propLabel = keys.label || "label";
    var propValue = keys.value || "value";
    this.model = null;
    this.children = null;
    this.vmCheckable = false;
    this.vmIsLeaf = false;
    this.vmIsFirst = false;
    this.vmIsLast = false;
    this.vmIsRest = true;
    this.vmIsLocked = false;

    var spec = _objectSpread(_objectSpread({}, defaultStatus), {}, {
      actived: false,
      expanded: false,
      checked: false
    }, data);

    var children = spec[propChildren];
    this.set(spec);
    this.label = spec[propLabel] || "";
    this.value = spec[propValue] || uniqueId__default["default"](prefix);
    this.tree.nodeMap.set(this.value, this);

    if (parent && parent instanceof TreeNode) {
      this.parent = parent;
    } else {
      this.parent = null;
    }

    if (children === true) {
      this.children = children;
    }

    this.level = 0;
    this.visible = true;
    this.actived = spec.actived;
    this.initActived();
    this.expanded = spec.expanded;
    this.initExpanded();
    this.checked = spec.checked;
    this.initChecked();
    this.update();
    tree.reflow(this);

    if (Array.isArray(children)) {
      this.append(children);
    } else if (children === true && !config.lazy) {
      this.loadChildren();
    }

    this.checked = false;
    this.indeterminate = false;
    this.updateChecked();
  }

  _createClass__default["default"](TreeNode, [{
    key: "initChecked",
    value: function initChecked() {
      var tree = this.tree,
          value = this.value,
          parent = this.parent;
      var checkStrictly = tree.config.checkStrictly;
      var checked = this.checked;
      checked = parent === null || parent === void 0 ? void 0 : parent.isChecked();

      if (checked && !checkStrictly) {
        tree.checkedMap.set(value, true);
      }

      this.checked = checked;
    }
  }, {
    key: "initExpanded",
    value: function initExpanded() {
      var tree = this.tree;
      var expanded = this.expanded;
      var config = tree.config;

      if (typeof config.expandLevel === "number" && this.getLevel() < config.expandLevel) {
        tree.expandedMap.set(this.value, true);
        expanded = true;
      }

      if (config.expandAll) {
        expanded = true;
      }

      if (this.children === true && config.lazy) {
        expanded = false;
      }

      if (expanded) {
        tree.expandedMap.set(this.value, true);
      } else {
        tree.expandedMap["delete"](this.value);
      }

      this.expanded = expanded;
    }
  }, {
    key: "initActived",
    value: function initActived() {
      var tree = this.tree,
          actived = this.actived;

      if (actived) {
        tree.activedMap.set(this.value, true);
      }
    }
  }, {
    key: "append",
    value: function append(data) {
      var _this = this;

      var list = [];

      if (!Array.isArray(data)) {
        list.push(data);
      } else {
        list.push.apply(list, _toConsumableArray__default["default"](data));
      }

      if (list.length <= 0) {
        return;
      }

      if (!Array.isArray(this.children)) {
        this.children = [];
      }

      var children = this.children,
          tree = this.tree;
      list.forEach(function (item) {
        var node = null;

        if (item instanceof TreeNode) {
          node = item;
          node.appendTo(_this.tree, _this);
        } else {
          node = new TreeNode(_this.tree, item, _this);
          children.push(node);
        }
      });
      tree.reflow(this);
      this.updateRelated();
    }
  }, {
    key: "appendTo",
    value: function appendTo(tree, parent, index) {
      var _this2 = this;

      var parentNode = parent;
      if (!parentNode) return;
      var targetParents = parentNode.getParents();
      var includeCurrent = targetParents.some(function (node) {
        return node.value === _this2.value;
      });

      if (includeCurrent) {
        return;
      }

      if (Array.isArray(parentNode.children)) {
        var targetIndex = 0;

        if (typeof index === "number") {
          targetIndex = index;
        }

        var targetPosNode = parentNode.children[targetIndex];

        if (targetPosNode.value === this.value) {
          return;
        }
      }

      this.remove();
      this.parent = parentNode;
      var siblings = null;

      if (parentNode instanceof TreeNode) {
        if (!Array.isArray(parentNode.children)) {
          parentNode.children = [];
        }

        siblings = parent.children;
      } else {
        siblings = tree.children;
      }

      if (Array.isArray(siblings)) {
        if (typeof index === "number") {
          siblings.splice(index, 0, this);
        } else {
          siblings.push(this);
        }
      }

      var nodes = this.walk();
      nodes.forEach(function (item) {
        var node = item;
        node.tree = tree;
        tree.nodeMap.set(node.value, node);

        if (node.expanded) {
          tree.expandedMap.set(node.value, true);
        }
      });
      var updateNodes = parentNode.walk();
      updateNodes.forEach(function (node) {
        node.update();
        node.updateChecked();
      });
      tree.reflow();
    }
  }, {
    key: "insert",
    value: function insert(item, index) {
      var tree = this.tree,
          parent = this.parent;
      var siblings = this.getSiblings();
      var node = null;

      if (item instanceof TreeNode) {
        node = item;
        node.appendTo(tree, parent, index);
      } else if (item) {
        node = new TreeNode(tree, item, parent);

        if (typeof index === "number") {
          siblings.splice(index, 0, node);
        }

        siblings.forEach(function (sibling) {
          sibling.update();
        });
      }

      tree.reflow();
    }
  }, {
    key: "insertBefore",
    value: function insertBefore(newData) {
      var index = this.getIndex();
      this.insert(newData, index);
    }
  }, {
    key: "insertAfter",
    value: function insertAfter(newData) {
      var index = this.getIndex();
      this.insert(newData, index + 1);
    }
  }, {
    key: "remove",
    value: function remove() {
      var tree = this.tree;
      var nodes = this.walk();
      var siblings = this.getSiblings();
      var index = this.getIndex();

      if (Array.isArray(siblings)) {
        siblings.splice(index, 1);
      }

      nodes.forEach(function (node) {
        node.clean();
      });
      siblings.forEach(function (node) {
        node.update();
      });
      this.updateParents();
      tree.reflow();
    }
  }, {
    key: "clean",
    value: function clean() {
      var tree = this.tree,
          value = this.value;
      tree.activedMap["delete"](value);
      tree.checkedMap["delete"](value);
      tree.expandedMap["delete"](value);
      tree.nodeMap["delete"](value);
    }
  }, {
    key: "loadChildren",
    value: function () {
      var _loadChildren = _asyncToGenerator__default["default"]( /*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee() {
        var config, list;
        return _regeneratorRuntime__default["default"].wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                config = get__default["default"](this, "tree.config") || {};

                if (!(this.children === true && !this.loading)) {
                  _context.next = 13;
                  break;
                }

                if (!(typeof config.load === "function")) {
                  _context.next = 13;
                  break;
                }

                this.loading = true;
                this.update();
                list = [];
                _context.next = 8;
                return config.load(this);

              case 8:
                list = _context.sent;
                this.tree.emit("load", {
                  node: this,
                  data: list
                });
                this.loading = false;

                if (Array.isArray(list) && list.length > 0) {
                  this.append(list);
                } else {
                  this.children = false;
                }

                this.update();

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

      function loadChildren() {
        return _loadChildren.apply(this, arguments);
      }

      return loadChildren;
    }()
  }, {
    key: "set",
    value: function set(item) {
      var _this3 = this;

      var tree = this.tree;
      var keys = Object.keys(item);
      keys.forEach(function (key) {
        if (hasOwnProperty.call(defaultStatus, key) || key === "label") {
          _this3[key] = item[key];
        }
      });
      tree.updated(this);
    }
  }, {
    key: "getParent",
    value: function getParent() {
      return this.parent;
    }
  }, {
    key: "getParents",
    value: function getParents() {
      var parents = [];
      var node = this.parent;

      while (node) {
        parents.push(node);
        node = node.parent;
      }

      return parents;
    }
  }, {
    key: "getSiblings",
    value: function getSiblings() {
      var parent = this.parent,
          tree = this.tree;
      var list = [];

      if (parent) {
        if (Array.isArray(parent.children)) {
          list = parent.children;
        }
      } else if (tree) {
        list = tree.children;
      }

      return list;
    }
  }, {
    key: "getRoot",
    value: function getRoot() {
      var parents = this.getParents();
      return parents[parents.length - 1] || null;
    }
  }, {
    key: "getIndex",
    value: function getIndex() {
      var list = this.getSiblings();
      return list.indexOf(this);
    }
  }, {
    key: "getPath",
    value: function getPath() {
      var nodes = this.getParents();
      nodes.unshift(this);
      return nodes.reverse();
    }
  }, {
    key: "getLevel",
    value: function getLevel() {
      var parents = this.getParents();
      return parents.length;
    }
  }, {
    key: "isRest",
    value: function isRest() {
      var _this$tree = this.tree,
          config = _this$tree.config,
          filterMap = _this$tree.filterMap;
      var rest = true;

      if (typeof config.filter === "function") {
        var nodeModel = this.getModel();
        rest = config.filter(nodeModel);
      }

      if (rest) {
        filterMap.set(this.value, true);
      } else if (filterMap.get(this.value)) {
        filterMap["delete"](this.value);
      }

      return rest;
    }
  }, {
    key: "isVisible",
    value: function isVisible() {
      var nodeMap = this.tree.nodeMap;
      var visible = true;

      if (this.vmIsLocked) {
        return true;
      }

      if (nodeMap.get(this.value)) {
        var filterVisible = this.isRest();
        var expandVisible = true;
        var parents = this.getParents();

        if (parents.length > 0) {
          expandVisible = parents.every(function (node) {
            return node.isExpanded();
          });
        }

        visible = expandVisible && filterVisible;
      } else {
        visible = false;
      }

      return visible;
    }
  }, {
    key: "isDisabled",
    value: function isDisabled() {
      if (this.vmIsLocked) return true;
      var treeDisabled = get__default["default"](this, "tree.config.disabled");
      return !!(treeDisabled || this.disabled);
    }
  }, {
    key: "isExpandMutex",
    value: function isExpandMutex() {
      return !!(get__default["default"](this, "tree.config.expandMutex") || this.expandMutex);
    }
  }, {
    key: "isActivable",
    value: function isActivable() {
      return !!(get__default["default"](this, "tree.config.activable") || this.activable);
    }
  }, {
    key: "isCheckable",
    value: function isCheckable() {
      return !!(get__default["default"](this, "tree.config.checkable") || this.checkable);
    }
  }, {
    key: "isActived",
    value: function isActived(map) {
      var tree = this.tree,
          value = this.value;
      var activedMap = map || tree.activedMap;
      return !!(tree.nodeMap.get(value) && activedMap.get(value));
    }
  }, {
    key: "isExpanded",
    value: function isExpanded(map) {
      var tree = this.tree,
          value = this.value,
          vmIsLocked = this.vmIsLocked;
      if (vmIsLocked) return true;
      var expandedMap = map || tree.expandedMap;
      return !!(tree.nodeMap.get(value) && expandedMap.get(value));
    }
  }, {
    key: "isChecked",
    value: function isChecked(map) {
      var children = this.children,
          tree = this.tree;
      var checkStrictly = tree.config.checkStrictly;
      var checked = false;
      var checkedMap = map || tree.checkedMap;

      if (tree.nodeMap.get(this.value)) {
        if (checkedMap.get(this.value)) {
          checked = true;
        } else if (Array.isArray(children) && children.length > 0 && !checkStrictly) {
          checked = children.every(function (node) {
            var childIsChecked = node.isChecked(checkedMap);
            return childIsChecked;
          });
        } else if (!checkStrictly) {
          var parents = this.getParents();
          checked = parents.some(function (node) {
            return checkedMap.get(node.value);
          });
        }
      }

      return !!checked;
    }
  }, {
    key: "isIndeterminate",
    value: function isIndeterminate() {
      var children = this.children,
          tree = this.tree;
      var checkStrictly = tree.config.checkStrictly;

      if (checkStrictly) {
        return false;
      }

      var indeterminate = false;

      if (Array.isArray(children)) {
        var childChecked = null;
        indeterminate = children.some(function (node) {
          if (node.isIndeterminate()) {
            return true;
          }

          if (childChecked === null) {
            childChecked = node.isChecked();
          }

          if (childChecked !== node.isChecked()) {
            return true;
          }

          return false;
        });
      }

      return indeterminate;
    }
  }, {
    key: "isFirst",
    value: function isFirst() {
      var siblings = this.getSiblings();
      return siblings[0] === this;
    }
  }, {
    key: "isLast",
    value: function isLast() {
      var siblings = this.getSiblings();
      return siblings[siblings.length - 1] === this;
    }
  }, {
    key: "isLeaf",
    value: function isLeaf() {
      var isLeaf = false;

      if (Array.isArray(this.children)) {
        isLeaf = this.children.length <= 0;
      } else {
        isLeaf = !this.children;
      }

      return isLeaf;
    }
  }, {
    key: "lock",
    value: function lock(lockState) {
      this.vmIsLocked = lockState;
      this.expanded = this.isExpanded();
      this.visible = this.isVisible();
    }
  }, {
    key: "afterExpanded",
    value: function afterExpanded() {
      this.update();

      if (this.expanded && this.children === true) {
        this.loadChildren();
      }
    }
  }, {
    key: "toggleExpanded",
    value: function toggleExpanded() {
      return this.setExpanded(!this.isExpanded());
    }
  }, {
    key: "setExpanded",
    value: function setExpanded(expanded, opts) {
      var tree = this.tree;

      var options = _objectSpread({
        directly: false
      }, opts);

      var map = tree.expandedMap;

      if (!options.directly) {
        map = new Map(tree.expandedMap);
      }

      if (expanded) {
        var shouldExpandNodes = [];
        shouldExpandNodes.push(this);

        if (get__default["default"](tree, "config.expandParent")) {
          this.getParents().forEach(function (node) {
            shouldExpandNodes.push(node);
          });
        }

        shouldExpandNodes.forEach(function (node) {
          var isExpandMutex = false;

          if (node.parent) {
            isExpandMutex = node.parent.isExpandMutex();
          } else {
            var _tree$config;

            isExpandMutex = tree === null || tree === void 0 ? void 0 : (_tree$config = tree.config) === null || _tree$config === void 0 ? void 0 : _tree$config.expandMutex;
          }

          if (isExpandMutex) {
            var siblings = node.getSiblings();
            siblings.forEach(function (snode) {
              map["delete"](snode.value);
            });
          }

          map.set(node.value, true);
        });
      } else {
        map["delete"](this.value);
      }

      if (options.directly) {
        this.afterExpanded();
        this.update();
        this.updateChildren();
      }

      return tree.getExpanded(map);
    }
  }, {
    key: "toggleActived",
    value: function toggleActived() {
      return this.setActived(!this.isActived());
    }
  }, {
    key: "setActived",
    value: function setActived(actived, opts) {
      var tree = this.tree;

      var options = _objectSpread({
        directly: false
      }, opts);

      var config = tree.config || {};
      var map = tree.activedMap;

      if (!options.directly) {
        map = new Map(tree.activedMap);
      }

      if (this.isActivable()) {
        if (actived) {
          if (!config.activeMultiple) {
            map.clear();
          }

          map.set(this.value, true);
        } else {
          map["delete"](this.value);
        }
      }

      if (options.directly) {
        this.update();
      }

      return tree.getActived(map);
    }
  }, {
    key: "toggleChecked",
    value: function toggleChecked() {
      return this.setChecked(!this.isChecked());
    }
  }, {
    key: "setChecked",
    value: function setChecked(checked, opts) {
      var tree = this.tree;
      var config = tree.config || {};

      var options = _objectSpread({
        directly: false
      }, opts);

      var map = tree.checkedMap;

      if (!options.directly) {
        map = new Map(tree.checkedMap);
      }

      if (this.isCheckable() && checked !== this.isChecked()) {
        if (config.checkStrictly) {
          if (checked) {
            map.set(this.value, true);
          } else {
            map["delete"](this.value);
          }
        } else {
          var children = this.walk();
          children.forEach(function (node) {
            if (checked) {
              map.set(node.value, true);
            } else {
              map["delete"](node.value);
            }
          });
          var parents = this.getParents();
          parents.forEach(function (node) {
            map["delete"](node.value);
          });
        }
      }

      if (options.directly) {
        if (config.checkStrictly) {
          this.updateChecked();
        } else {
          var relatedNodes = tree.getRelatedNodes([this.value]);
          relatedNodes.forEach(function (node) {
            node.updateChecked();
          });
        }
      }

      return tree.getChecked(map);
    }
  }, {
    key: "update",
    value: function update() {
      this.level = this.getLevel();
      this.actived = this.isActived();
      this.expanded = this.isExpanded();
      this.vmCheckable = this.isCheckable();
      this.visible = this.isVisible();
      this.vmIsRest = this.isRest();
      this.vmIsFirst = this.isFirst();
      this.vmIsLast = this.isLast();
      this.vmIsLeaf = this.isLeaf();
      this.tree.updated(this);
    }
  }, {
    key: "updateChecked",
    value: function updateChecked() {
      var tree = this.tree;
      this.vmCheckable = this.isCheckable();

      if (this.vmCheckable && !this.disabled) {
        this.checked = this.isChecked();

        if (this.checked) {
          tree.checkedMap.set(this.value, true);
        }

        this.indeterminate = this.isIndeterminate();
        tree.updated(this);
      }
    }
  }, {
    key: "updateChildren",
    value: function updateChildren() {
      var children = this.children;

      if (Array.isArray(children)) {
        children.forEach(function (node) {
          node.update();
          node.updateChecked();
          node.updateChildren();
        });
      }
    }
  }, {
    key: "updateParents",
    value: function updateParents() {
      var parent = this.parent;

      if (parent) {
        parent.update();
        parent.updateChecked();
        parent.updateParents();
      }
    }
  }, {
    key: "updateRelated",
    value: function updateRelated() {
      var tree = this.tree;
      var relatedNodes = tree.getRelatedNodes([this.value]);
      relatedNodes.forEach(function (node) {
        node.update();
        node.updateChecked();
      });
      tree.reflow();
    }
  }, {
    key: "walk",
    value: function walk() {
      var children = this.children;
      var list = [];
      list.push(this);

      if (Array.isArray(children) && children.length > 0) {
        children.forEach(function (node) {
          list = list.concat(node.walk());
        });
      }

      return list;
    }
  }, {
    key: "getModel",
    value: function getModel() {
      var model = this.model;

      if (!model) {
        model = _common_js_tree_treeNodeModel.createNodeModel(this);
        this.model = model;
      }

      _common_js_tree_treeNodeModel.updateNodeModel(model, this);
      return model;
    }
  }]);

  return TreeNode;
}();

exports.TreeNode = TreeNode;
exports["default"] = TreeNode;
//# sourceMappingURL=tree-node.js.map
