var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
import _ from 'lodash';
import { Store } from './Store';
var TreeStore = /** @class */ (function (_super) {
    __extends(TreeStore, _super);
    function TreeStore(params) {
        var _this = _super.call(this, params) || this;
        _this.treeHashMap = {};
        params.pageSize = 10000;
        return _this;
    }
    TreeStore.prototype.useBackend = function () {
        return false;
    };
    TreeStore.prototype.getChildrenKey = function () {
        return 'children';
    };
    TreeStore.prototype.getChildren = function (node) {
        return node[this.getChildrenKey()];
    };
    TreeStore.prototype.addChild = function (parent, child) {
        var childrenKey = this.getChildrenKey();
        if (!parent[childrenKey]) {
            parent[childrenKey] = [];
        }
        parent[childrenKey].push(child);
    };
    TreeStore.prototype.getParentKey = function () {
        return 'parentId';
    };
    TreeStore.prototype.getParent = function (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 undefined;
        }
        return hashMap[parentId];
    };
    TreeStore.prototype.getHashMap = function () {
        return this.treeHashMap;
    };
    TreeStore.prototype.getNodeById = function (id) {
        return this.getHashMap()[id];
    };
    TreeStore.prototype.countItems = function (list) {
        return list.length;
    };
    TreeStore.prototype.addParentsToResultArray = function (node, array, hashMap) {
        while (this.getParent(node)) {
            var parent_1 = this.getParent(node, hashMap);
            array.push(parent_1);
            node = parent_1;
        }
    };
    TreeStore.prototype.addChildrenToResultArray = function (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); });
    };
    TreeStore.prototype.getFilteredTree = function (list, hashMap) {
        var _this = this;
        var filtered = this.getFiltered(list);
        if (list.length === filtered.length) {
            return filtered;
        }
        var balanced = filtered.reduce(function (result, item) {
            _this.addChildrenToResultArray(item, result, hashMap);
            _this.addParentsToResultArray(item, result, hashMap);
            return result;
        }, filtered.slice());
        return _.uniq(balanced);
    };
    TreeStore.prototype.getItemsHashMap = function (data) {
        var _this = this;
        var items = {};
        data.forEach(function (item) {
            items[item[_this.primaryKey]] = item;
        });
        return items;
    };
    TreeStore.prototype.assembleTree = function (nodes, hashMap) {
        var _this = this;
        var keysQueue = nodes.map(function (node) { return node[_this.primaryKey]; });
        var tree = [];
        keysQueue.forEach(function (key) {
            var node = hashMap[key];
            var parent = _this.getParent(node, hashMap);
            if (parent) {
                _this.addChild(parent, node);
            }
            else {
                tree.push(node);
            }
        });
        return tree;
    };
    TreeStore.prototype.convert = function (data) {
        this.rawData = _super.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;
    };
    TreeStore.prototype.calculate = function (data) {
        var _this = this;
        var hasRawDataChanges = !_.isEqual(this.rawData, data);
        var copy = _.cloneDeep(data);
        copy.forEach(function (item) {
            delete item[_this.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);
    };
    TreeStore.prototype.applyCallbackToSubtree = function (node, index, fn, level) {
        var _this = this;
        fn(node, index, level);
        var children = this.getChildren(node);
        if (children && children.length > 0) {
            children.forEach(function (child, childIndex) {
                _this.applyCallbackToSubtree(child, childIndex, fn, (level || 0) + 1);
            });
        }
    };
    TreeStore.prototype.applyCallbackToParents = function (node, fn) {
        while (this.getParent(node)) {
            var parent_2 = this.getParent(node);
            fn(parent_2);
            node = parent_2;
        }
    };
    TreeStore.prototype.loadWithParams = function () {
        throw new Error('Not implemented');
    };
    return TreeStore;
}(Store));
export { TreeStore };
//# sourceMappingURL=TreeStore.js.map