"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

exports.__esModule = true;
exports.TreeStore = void 0;

var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));

var _lodash = _interopRequireDefault(require("lodash"));

var _Store2 = _interopRequireDefault(require("./Store"));

var TreeStore =
/*#__PURE__*/
function (_Store) {
  (0, _inheritsLoose2.default)(TreeStore, _Store);

  function TreeStore(params) {
    params.pageSize = 10000;
    return _Store.call(this, params) || this;
  }

  var _proto = TreeStore.prototype;

  _proto.useBackend = function useBackend() {
    return false;
  };

  _proto.getChildrenKey = function getChildrenKey() {
    return 'children';
  };

  _proto.getChildren = function getChildren(node) {
    return node[this.getChildrenKey()];
  };

  _proto.addChild = function addChild(parent, child) {
    var childrenKey = this.getChildrenKey();

    if (!parent[childrenKey]) {
      parent[childrenKey] = [];
    }

    parent[childrenKey].push(child);
  };

  _proto.getParentKey = function getParentKey() {
    return 'parentId';
  };

  _proto.getParent = function getParent(node, hashMap) {
    hashMap = hashMap || this.treeHashMap;
    var parentId = node[this.getParentKey()];

    if (parentId === undefined && parentId === null) {
      // eslint-disable-next-line no-console
      console.warn("Tree node with id " + node[this.primaryKey] + " is not connected with tree. Please, check your data.");
      return;
    }

    return hashMap[parentId];
  };

  _proto.getHashMap = function getHashMap() {
    return this.treeHashMap;
  };

  _proto.getNodeById = function getNodeById(id) {
    return this.getHashMap()[id];
  };

  _proto.countItems = function countItems(list) {
    return list.length;
  };

  _proto.addParentsToResultArray = function addParentsToResultArray(node, array, hashMap) {
    while (this.getParent(node)) {
      var parent = this.getParent(node, hashMap);
      array.push(parent);
      node = parent;
    }
  };

  _proto.addChildrenToResultArray = function addChildrenToResultArray(node, array, hashMap) {
    var _this = this;

    var foundChildren = Object.values(hashMap).reduce(function (children, childToCheck) {
      var parent = _this.getParent(childToCheck);

      if (!parent || parent[_this.primaryKey] !== node[_this.primaryKey]) {
        return children;
      }

      array.push(childToCheck);
      children.push(childToCheck);
      return children;
    }, []);
    foundChildren.forEach(function (child) {
      return _this.addChildrenToResultArray(child, array, hashMap);
    });
  };

  _proto.getFilteredTree = function getFilteredTree(list, hashMap) {
    var _this2 = this;

    var filtered = this.getFiltered(list);

    if (list.length === filtered.length) {
      return filtered;
    }

    var balanced = filtered.reduce(function (result, item) {
      _this2.addChildrenToResultArray(item, result, hashMap);

      _this2.addParentsToResultArray(item, result, hashMap);

      return result;
    }, [].concat(filtered));
    return _lodash.default.uniq(balanced);
  };

  _proto.getItemsHashMap = function getItemsHashMap(data) {
    var _this3 = this;

    var items = {};
    data.forEach(function (item) {
      items[item[_this3.primaryKey]] = item;
    });
    return items;
  };

  _proto.assembleTree = function assembleTree(nodes, hashMap) {
    var _this4 = this;

    var keysQueue = nodes.map(function (node) {
      return node[_this4.primaryKey];
    });
    var tree = [];
    keysQueue.forEach(function (key) {
      var node = hashMap[key];

      var parent = _this4.getParent(node, hashMap);

      if (parent) {
        _this4.addChild(parent, node);
      } else {
        tree.push(node);
      }
    });
    return tree;
  };

  _proto.convert = function convert(data) {
    this.rawData = _Store.prototype.convert.call(this, data);
    this.totalCount = this.countItems(this.rawData);
    this.treeHashMap = this.getItemsHashMap(this.rawData);
    this.assembleTree(this.rawData, this.treeHashMap); // it mutates this.rawData

    return this.rawData;
  };

  _proto.calculate = function calculate(data) {
    var _this5 = this;

    var hasRawDataChanges = !_lodash.default.isEqual(this.rawData, data);

    var copy = _lodash.default.cloneDeep(data);

    copy.forEach(function (item) {
      delete item[_this5.getChildrenKey()];
    });
    var hashMap = this.getItemsHashMap(copy);
    var list = this.getFilteredTree(copy, hashMap);
    this.filteredCount = this.countItems(list);
    list = this.getSorted(list);
    this.data = this.assembleTree(list, hashMap);
    this.notifyChanges(hasRawDataChanges);
  };

  _proto.applyCallbackToSubtree = function applyCallbackToSubtree(node, index, fn, level) {
    var _this6 = this;

    if (level === void 0) {
      level = 1;
    }

    fn(node, index, level);
    var children = this.getChildren(node);

    if (children && children.length > 0) {
      children.forEach(function (child, childIndex) {
        _this6.applyCallbackToSubtree(child, childIndex, fn, level + 1);
      });
    }
  };

  _proto.applyCallbackToParents = function applyCallbackToParents(node, fn) {
    while (this.getParent(node)) {
      var parent = this.getParent(node);
      fn(parent);
      node = parent;
    }
  };

  _proto.loadWithParams = function loadWithParams() {
    throw new Error('Not implemented');
  };

  return TreeStore;
}(_Store2.default);

exports.TreeStore = TreeStore;