import * as sort from "../tools/sort";

import { AggregationType, HierarchyState } from "../ts-types";

import { applyChainSafe, getOrApply, obj, isPromise, emptyFn } from "../tools/helper";

import { EventTarget } from "../event/EventTarget";

import { computeChildrenNodeLength, getValueByPath, isAllDigits } from "../tools/util";

import { arrayEqual, cloneDeep, isNumber, isObject, isValid } from "@visactor/vutils";

import { RecordAggregator, SumAggregator, CountAggregator, MaxAggregator, MinAggregator, AvgAggregator, NoneAggregator, CustomAggregator } from "../ts-types/dataset/aggregation";

function isFieldAssessor(field) {
    if (obj.isObject(field)) {
        const a = field;
        if (isValid(a.get) && isValid(a.set)) return !0;
    }
    return !1;
}

const EVENT_TYPE = {
    SOURCE_LENGTH_UPDATE: "source_length_update",
    CHANGE_ORDER: "change_order"
};

export function getValue(value, promiseCallBack) {
    const maybePromiseOrValue = getOrApply(value);
    if (isPromise(maybePromiseOrValue)) {
        const promiseValue = maybePromiseOrValue.then((r => (promiseCallBack(r), r)));
        return promiseCallBack(promiseValue), promiseValue;
    }
    return maybePromiseOrValue;
}

export function getField(record, field, col, row, table, promiseCallBack) {
    if (null == record) return;
    if (isPromise(record)) return record.then((r => getField(r, field, col, row, table, promiseCallBack)));
    const fieldGet = isFieldAssessor(field) ? field.get : field;
    if ((void 0 === fieldGet || "" === fieldGet) && Array.isArray(record)) {
        return record[col - table.leftRowSeriesNumberCount];
    }
    if (isObject(record) && fieldGet in record) {
        return getValue(record[fieldGet], promiseCallBack);
    }
    if ("function" == typeof fieldGet) {
        return getValue(fieldGet(record, col, row, table), promiseCallBack);
    }
    if (Array.isArray(fieldGet)) {
        return getValue(getValueByPath(record, [ ...fieldGet ]), promiseCallBack);
    }
    const fieldArray = `${fieldGet}`.split(".");
    if (fieldArray.length <= 1) {
        return getValue(record[fieldGet], promiseCallBack);
    }
    return getValue(applyChainSafe(record, ((val, name) => getField(val, name, col, row, table, emptyFn)), ...fieldArray), promiseCallBack);
}

function _getIndex(sortedIndexMap, index) {
    if (!sortedIndexMap) return index;
    const mapIndex = sortedIndexMap[index];
    return isValid(mapIndex) ? mapIndex : index;
}

export class DataSource extends EventTarget {
    static get EVENT_TYPE() {
        return EVENT_TYPE;
    }
    constructor(dataSourceObj, dataConfig, pagination, columns, rowHierarchyType, hierarchyExpandLevel) {
        var _a;
        super(), this.addRecordRule = "Object", this.currentIndexedData = [], this.hierarchyExpandLevel = 0, 
        this.hasHierarchyStateExpand = !1, this.beforeChangedRecordsMap = new Map, this.registedAggregators = {}, 
        this.rowHierarchyType = "grid", this.fieldAggregators = [], this.addRecordRule = (null == dataConfig ? void 0 : dataConfig.addRecordRule) || "Object", 
        this.registerAggregators(), this.dataSourceObj = dataSourceObj, this.dataConfig = dataConfig, 
        this._get = null == dataSourceObj ? void 0 : dataSourceObj.get, this.columns = columns, 
        this._source = (null == dataSourceObj ? void 0 : dataSourceObj.records) ? this.processRecords(null == dataSourceObj ? void 0 : dataSourceObj.records) : dataSourceObj, 
        this._sourceLength = (null === (_a = this._source) || void 0 === _a ? void 0 : _a.length) || 0, 
        this.sortedIndexMap = new Map, this._currentPagerIndexedData = [], this.userPagination = pagination, 
        this.pagination = pagination || {
            totalCount: this._sourceLength,
            perPageCount: this._sourceLength,
            currentPage: 0
        }, hierarchyExpandLevel >= 1 && (this.hierarchyExpandLevel = hierarchyExpandLevel), 
        this.currentIndexedData = Array.from({
            length: this._sourceLength
        }, ((_, i) => i)), "tree" === rowHierarchyType && this.initTreeHierarchyState(), 
        this.rowHierarchyType = rowHierarchyType, this.updatePagerData();
    }
    initTreeHierarchyState() {
        var _a, _b;
        this._sourceLength = (null === (_a = this._source) || void 0 === _a ? void 0 : _a.length) || 0, 
        this.currentIndexedData = Array.from({
            length: this._sourceLength
        }, ((_, i) => i));
        let nodeLength = this._sourceLength;
        for (let i = 0; i < nodeLength; i++) {
            const indexKey = this.currentIndexedData[i], nodeData = this.getOriginalRecord(indexKey);
            if (!nodeData) continue;
            const children = null !== (_b = nodeData.filteredChildren) && void 0 !== _b ? _b : nodeData.children;
            if ((null == children ? void 0 : children.length) > 0) {
                if (this.hierarchyExpandLevel > 1 ? !nodeData.hierarchyState && (nodeData.hierarchyState = HierarchyState.expand) : !nodeData.hierarchyState && (nodeData.hierarchyState = HierarchyState.collapse), 
                this.hasHierarchyStateExpand = !0, nodeData.hierarchyState === HierarchyState.collapse) continue;
                const childrenLength = this.initChildrenNodeHierarchy(indexKey, this.hierarchyExpandLevel, 2, nodeData);
                i += childrenLength, nodeLength += childrenLength;
            } else !0 === nodeData.children && !nodeData.hierarchyState && (nodeData.hierarchyState = HierarchyState.collapse);
        }
    }
    supplementConfig(pagination, columns, rowHierarchyType, hierarchyExpandLevel) {
        var _a;
        this.columns = columns, this._sourceLength = (null === (_a = this._source) || void 0 === _a ? void 0 : _a.length) || 0, 
        this.sortedIndexMap = new Map, this._currentPagerIndexedData = [], this.userPagination = pagination, 
        this.pagination = pagination || {
            totalCount: this._sourceLength,
            perPageCount: this._sourceLength,
            currentPage: 0
        }, hierarchyExpandLevel >= 1 && (this.hierarchyExpandLevel = hierarchyExpandLevel), 
        this.currentIndexedData = Array.from({
            length: this._sourceLength
        }, ((_, i) => i)), "tree" === rowHierarchyType && this.initTreeHierarchyState(), 
        this.rowHierarchyType = rowHierarchyType, this.updatePagerData();
    }
    registerAggregator(type, aggregator) {
        this.registedAggregators[type] = aggregator;
    }
    registerAggregators() {
        this.registerAggregator(AggregationType.RECORD, RecordAggregator), this.registerAggregator(AggregationType.SUM, SumAggregator), 
        this.registerAggregator(AggregationType.COUNT, CountAggregator), this.registerAggregator(AggregationType.MAX, MaxAggregator), 
        this.registerAggregator(AggregationType.MIN, MinAggregator), this.registerAggregator(AggregationType.AVG, AvgAggregator), 
        this.registerAggregator(AggregationType.NONE, NoneAggregator), this.registerAggregator(AggregationType.CUSTOM, CustomAggregator);
    }
    updateColumns(columns) {
        this.columns = columns;
    }
    _generateFieldAggragations() {
        const columnObjs = this.columns;
        this.fieldAggregators = [];
        const processColumn = column => {
            delete column.vtable_aggregator;
            const field = column.field, aggregation = column.aggregation;
            if (aggregation) if (Array.isArray(aggregation)) for (const item of aggregation) {
                const aggregator = new this.registedAggregators[item.aggregationType]({
                    field: field,
                    formatFun: item.formatFun,
                    isRecord: !0,
                    aggregationFun: item.aggregationFun
                });
                this.fieldAggregators.push(aggregator), column.vtable_aggregator || (column.vtable_aggregator = []), 
                column.vtable_aggregator.push(aggregator);
            } else {
                const aggregator = new this.registedAggregators[aggregation.aggregationType]({
                    field: field,
                    formatFun: aggregation.formatFun,
                    isRecord: !0,
                    aggregationFun: aggregation.aggregationFun
                });
                this.fieldAggregators.push(aggregator), column.vtable_aggregator = aggregator;
            }
        }, traverseColumns = columns => {
            if (columns && 0 !== columns.length) for (const column of columns) processColumn(column), 
            column.columns && traverseColumns(column.columns);
        };
        traverseColumns(columnObjs);
    }
    processRecords(records) {
        var _a, _b, _c, _d, _e, _f, _g, _h;
        this._generateFieldAggragations();
        const filteredRecords = [], isHasAggregation = this.fieldAggregators.length >= 1;
        if ((null === (_b = null === (_a = this.dataConfig) || void 0 === _a ? void 0 : _a.filterRules) || void 0 === _b ? void 0 : _b.length) >= 1 || (null === (_c = this.lastFilterRules) || void 0 === _c ? void 0 : _c.length) >= 1 || isHasAggregation) {
            for (let i = 0, len = records.length; i < len; i++) {
                const record = records[i];
                null != record && ((null === (_e = null === (_d = this.dataConfig) || void 0 === _d ? void 0 : _d.filterRules) || void 0 === _e ? void 0 : _e.length) >= 1 ? this.filterRecord(record) && (filteredRecords.push(record), 
                "tree" === this.rowHierarchyType && record.children && (record.filteredChildren = this.filteredChildren(record.children)), 
                isHasAggregation && this.processRecord(record)) : (null === (_f = this.lastFilterRules) || void 0 === _f ? void 0 : _f.length) >= 1 ? (this.clearFilteredChildren(record), 
                isHasAggregation && this.processRecord(record)) : isHasAggregation && this.processRecord(record));
            }
            if ((null === (_h = null === (_g = this.dataConfig) || void 0 === _g ? void 0 : _g.filterRules) || void 0 === _h ? void 0 : _h.length) >= 1) return filteredRecords;
        }
        return records;
    }
    filteredChildren(records) {
        const filteredRecords = [];
        for (let i = 0, len = records.length; i < len; i++) {
            const record = records[i];
            this.filterRecord(record) && (filteredRecords.push(record), record.children && (record.filteredChildren = this.filteredChildren(record.children)));
        }
        return filteredRecords;
    }
    processRecord(record) {
        for (let i = 0; i < this.fieldAggregators.length; i++) {
            this.fieldAggregators[i].push(record);
        }
    }
    initChildrenNodeHierarchy(indexKey, hierarchyExpandLevel, currentLevel, nodeData) {
        var _a, _b, _c;
        let childTotalLength = 0;
        const nodeLength = nodeData.filteredChildren ? nodeData.filteredChildren.length : null !== (_b = null === (_a = nodeData.children) || void 0 === _a ? void 0 : _a.length) && void 0 !== _b ? _b : 0;
        for (let j = 0; j < nodeLength; j++) {
            (currentLevel <= hierarchyExpandLevel || nodeData.hierarchyState === HierarchyState.expand) && (childTotalLength += 1);
            const childNodeData = nodeData.filteredChildren ? nodeData.filteredChildren[j] : nodeData.children[j], childIndexKey = Array.isArray(indexKey) ? indexKey.concat(j) : [ indexKey, j ];
            (currentLevel <= hierarchyExpandLevel || nodeData.hierarchyState === HierarchyState.expand) && this.currentIndexedData.splice(this.currentIndexedData.indexOf(indexKey) + childTotalLength, 0, childIndexKey), 
            (childNodeData.filteredChildren ? childNodeData.filteredChildren.length > 0 : (null === (_c = childNodeData.children) || void 0 === _c ? void 0 : _c.length) > 0) && (currentLevel < hierarchyExpandLevel || childNodeData.hierarchyState === HierarchyState.expand ? (!childNodeData.hierarchyState && (childNodeData.hierarchyState = HierarchyState.expand), 
            this.hasHierarchyStateExpand = !0) : !childNodeData.hierarchyState && (childNodeData.hierarchyState = HierarchyState.collapse)), 
            childNodeData.hierarchyState === HierarchyState.expand && (childTotalLength += this.initChildrenNodeHierarchy(childIndexKey, hierarchyExpandLevel, currentLevel + 1, childNodeData)), 
            !0 === childNodeData.children && !childNodeData.hierarchyState && (childNodeData.hierarchyState = HierarchyState.collapse);
        }
        return childTotalLength;
    }
    updatePagination(pagination) {
        this.pagination = pagination || {
            totalCount: this._sourceLength,
            perPageCount: this._sourceLength,
            currentPage: 0
        }, this.updatePagerData();
    }
    updatePagerData() {
        const {currentIndexedData: currentIndexedData} = this, {perPageCount: perPageCount, currentPage: currentPage} = this.pagination, startIndex = perPageCount * (currentPage || 0), endIndex = startIndex + perPageCount;
        if (this._currentPagerIndexedData.length = 0, currentIndexedData && currentIndexedData.length > 0) {
            let firstLevelIndex = -1;
            for (let i = 0; i < currentIndexedData.length; i++) if ((Array.isArray(currentIndexedData[i]) && 1 === currentIndexedData[i].length || !Array.isArray(currentIndexedData[i])) && firstLevelIndex++, 
            firstLevelIndex >= startIndex && firstLevelIndex < endIndex) this._currentPagerIndexedData.push(currentIndexedData[i]); else if (firstLevelIndex >= endIndex) break;
        } else if (this._sourceLength > 0) throw new Error("currentIndexedData should has values!");
    }
    getRecordIndexPaths(bodyShowIndex) {
        return this._currentPagerIndexedData[bodyShowIndex];
    }
    get records() {
        return Array.isArray(this._source) ? this._source : [];
    }
    get source() {
        return this._source;
    }
    get(index) {
        return this.getOriginalRecord(_getIndex(this.currentPagerIndexedData, index));
    }
    getRaw(index) {
        return this.getRawRecord(_getIndex(this.currentPagerIndexedData, index));
    }
    getIndexKey(index) {
        return _getIndex(this.currentPagerIndexedData, index);
    }
    getTableIndex(colOrRow) {
        return Array.isArray(colOrRow) ? "tree" === this.rowHierarchyType ? this.currentPagerIndexedData.findIndex((value => arrayEqual(value, colOrRow))) : this.currentPagerIndexedData.findIndex((value => value === colOrRow[0])) : this.currentPagerIndexedData.findIndex((value => value === colOrRow));
    }
    getField(index, field, col, row, table) {
        return this.getOriginalField(_getIndex(this.currentPagerIndexedData, index), field, col, row, table);
    }
    getRawField(index, field, col, row, table) {
        return this.getRawFieldData(_getIndex(this.currentPagerIndexedData, index), field, col, row, table);
    }
    hasField(index, field) {
        return this.hasOriginalField(_getIndex(this.currentPagerIndexedData, index), field);
    }
    getHierarchyState(index) {
        var _a;
        const record = this.getOriginalRecord(this.currentPagerIndexedData[index]);
        if (null == record ? void 0 : record.hierarchyState) {
            const hierarchyState = record.hierarchyState;
            if ((null === (_a = record.children) || void 0 === _a ? void 0 : _a.length) > 0 || !0 === record.children) return hierarchyState;
        }
        return null;
    }
    toggleHierarchyState(index, bodyStartIndex, bodyEndIndex) {
        const oldIndexedData = this.currentIndexedData.slice(0), indexed = this.getIndexKey(index), state = this.getHierarchyState(index), data = this.getOriginalRecord(indexed);
        if (this.clearSortedIndexMap(), state === HierarchyState.collapse) data.hierarchyState = HierarchyState.expand, 
        this.pushChildrenNode(indexed, HierarchyState.expand, data), this.hasHierarchyStateExpand = !0; else if (state === HierarchyState.expand) {
            const childrenLength = computeChildrenNodeLength(indexed, state, data);
            this.currentIndexedData.splice(this.currentIndexedData.indexOf(indexed) + 1, childrenLength), 
            data.hierarchyState = HierarchyState.collapse;
        }
        this.updatePagerData();
        const add = [], remove = [];
        if (state === HierarchyState.collapse) {
            const addLength = this.currentIndexedData.length - oldIndexedData.length;
            for (let i = 0; i < addLength; i++) add.push(index + i + 1);
        } else if (state === HierarchyState.expand) {
            const removeLength = oldIndexedData.length - this.currentIndexedData.length;
            for (let i = 0; i < removeLength; i++) remove.push(index + i + 1);
        }
        return {
            add: add,
            remove: remove
        };
    }
    pushChildrenNode(indexKey, hierarchyState, nodeData) {
        var _a, _b;
        if (!hierarchyState || hierarchyState === HierarchyState.collapse || hierarchyState === HierarchyState.none) return 0;
        let childrenLength = 0;
        const children = nodeData.filteredChildren ? nodeData.filteredChildren : nodeData.children;
        if (children) {
            const subNodeSortedIndexArray = Array.from({
                length: children.length
            }, ((_, i) => i));
            null === (_a = this.lastSortStates) || void 0 === _a || _a.forEach((state => {
                "normal" !== state.order && sort.sort((index => isValid(subNodeSortedIndexArray[index]) ? subNodeSortedIndexArray[index] : subNodeSortedIndexArray[index] = index), ((index, rel) => {
                    subNodeSortedIndexArray[index] = rel;
                }), children.length, state.orderFn, state.order, (index => this.getOriginalField(Array.isArray(indexKey) ? indexKey.concat([ index ]) : [ indexKey, index ], state.field)));
            }));
            for (let i = 0; i < subNodeSortedIndexArray.length; i++) {
                childrenLength += 1;
                const childIndex = Array.isArray(indexKey) ? indexKey.concat([ subNodeSortedIndexArray[i] ]) : [ indexKey, subNodeSortedIndexArray[i] ];
                this.currentIndexedData.splice(this.currentIndexedData.indexOf(indexKey) + childrenLength, 0, childIndex);
                const childData = this.getOriginalRecord(childIndex);
                !childData.hierarchyState && (null !== (_b = childData.filteredChildren) && void 0 !== _b ? _b : childData.children) && (childData.hierarchyState = HierarchyState.collapse), 
                childrenLength += this.pushChildrenNode(childIndex, childData.hierarchyState, children[subNodeSortedIndexArray[i]]);
            }
        }
        return childrenLength;
    }
    changeFieldValue(value, index, field, col, row, table) {
        var _a;
        if (null !== field && index >= 0) {
            const dataIndex = this.getIndexKey(index);
            if (this.cacheBeforeChangedRecord(dataIndex, table), void 0 !== field && "" !== field || (field = col - table.leftRowSeriesNumberCount), 
            "string" == typeof field || "number" == typeof field) {
                const beforeChangedValue = null === (_a = this.beforeChangedRecordsMap.get(dataIndex.toString())) || void 0 === _a ? void 0 : _a[field], record = this.getOriginalRecord(dataIndex);
                let formatValue = value;
                "number" == typeof beforeChangedValue && isAllDigits(value) && (formatValue = parseFloat(value)), 
                isPromise(record) ? record.then((record => {
                    record[field] = formatValue;
                })).catch((err => {})) : record ? record[field] = formatValue : (this.records[dataIndex] = "Array" === this.addRecordRule ? [] : {}, 
                this.records[dataIndex][field] = formatValue);
            }
        }
    }
    changeFieldValueByRecordIndex(value, recordIndex, field, table) {
        var _a, _b, _c, _d;
        if (null === field) return;
        if (null == recordIndex) return;
        const rawKey = recordIndex.toString();
        if (!this.beforeChangedRecordsMap.has(rawKey)) {
            const rawRecords = Array.isArray(null === (_a = this.dataSourceObj) || void 0 === _a ? void 0 : _a.records) ? this.dataSourceObj.records : null, originRecord = rawRecords ? Array.isArray(recordIndex) ? getValueFromDeepArray(rawRecords, recordIndex) : rawRecords[recordIndex] : void 0;
            this.beforeChangedRecordsMap.set(rawKey, null !== (_b = cloneDeep(originRecord, void 0, [ "vtable_gantt_linkedFrom", "vtable_gantt_linkedTo" ])) && void 0 !== _b ? _b : {});
        }
        if ("string" == typeof field || "number" == typeof field) {
            const beforeChangedValue = null === (_c = this.beforeChangedRecordsMap.get(rawKey)) || void 0 === _c ? void 0 : _c[field], rawRecords = Array.isArray(null === (_d = this.dataSourceObj) || void 0 === _d ? void 0 : _d.records) ? this.dataSourceObj.records : null, record = rawRecords ? Array.isArray(recordIndex) ? getValueFromDeepArray(rawRecords, recordIndex) : rawRecords[recordIndex] : void 0;
            let formatValue = value;
            "number" == typeof beforeChangedValue && isAllDigits(value) && (formatValue = parseFloat(value)), 
            record ? record[field] = formatValue : rawRecords && "number" == typeof recordIndex && (rawRecords[recordIndex] = "Array" === this.addRecordRule ? [] : {}, 
            rawRecords[recordIndex][field] = formatValue);
        }
    }
    cacheBeforeChangedRecord(dataIndex, table) {
        var _a;
        if (!this.beforeChangedRecordsMap.has(dataIndex.toString())) {
            const originRecord = this.getOriginalRecord(dataIndex);
            this.beforeChangedRecordsMap.set(dataIndex.toString(), null !== (_a = cloneDeep(originRecord, void 0, [ "vtable_gantt_linkedFrom", "vtable_gantt_linkedTo" ])) && void 0 !== _a ? _a : {});
        }
    }
    setRecord(record, index) {
        var _a, _b;
        let isAdd = !0;
        if ((null === (_b = null === (_a = this.dataConfig) || void 0 === _a ? void 0 : _a.filterRules) || void 0 === _b ? void 0 : _b.length) >= 1 && (this.filterRecord(record) ? "tree" === this.rowHierarchyType && record.children && (record.filteredChildren = this.filteredChildren(record.children)) : isAdd = !1), 
        isAdd && Array.isArray(this.records)) {
            const indexed = this.getIndexKey(index);
            Array.isArray(indexed) || this.records.splice(indexed, 1, record);
        }
    }
    _getRawRecordsArray() {
        var _a;
        const rawRecords = null === (_a = this.dataSourceObj) || void 0 === _a ? void 0 : _a.records;
        return Array.isArray(rawRecords) ? rawRecords : null;
    }
    _hasFilterInEffect() {
        var _a, _b, _c, _d, _e;
        return (null !== (_c = null === (_b = null === (_a = this.dataConfig) || void 0 === _a ? void 0 : _a.filterRules) || void 0 === _b ? void 0 : _b.length) && void 0 !== _c ? _c : 0) >= 1 || (null !== (_e = null === (_d = this.lastFilterRules) || void 0 === _d ? void 0 : _d.length) && void 0 !== _e ? _e : 0) >= 1;
    }
    _normalizeInsertIndex(index, length) {
        return null == index || index > length ? length : index < 0 ? 0 : index;
    }
    _mapViewInsertIndexToRawInsertIndex(rawRecords, viewIndex) {
        if (viewIndex >= this.records.length) return rawRecords.length;
        if (viewIndex <= 0) return 0;
        const prevRecord = this.records[viewIndex - 1], rawIndex = rawRecords.indexOf(prevRecord);
        return rawIndex >= 0 ? rawIndex + 1 : rawRecords.length;
    }
    _resetIndexingFromViewRecords() {
        if (this._sourceLength = this.records.length, this.currentIndexedData = Array.from({
            length: this._sourceLength
        }, ((_, i) => i)), "tree" === this.rowHierarchyType && this.initTreeHierarchyState(), 
        this.userPagination) return this.pagination.totalCount = this._sourceLength, void this.updatePagerData();
        this.pagination.perPageCount = this._sourceLength, this.pagination.totalCount = this._sourceLength, 
        this.updatePagerData();
    }
    addRecord(record, index, syncToOriginalRecords = !1) {
        var _a, _b, _c;
        if (!syncToOriginalRecords) {
            if (Array.isArray(this.records)) {
                this.records.splice(index, 0, record), this.adjustBeforeChangedRecordsMap(index, 1), 
                this.currentIndexedData.push(this.currentIndexedData.length), this._sourceLength += 1;
                for (let i = 0; i < this.fieldAggregators.length; i++) this.fieldAggregators[i].push(record);
                if ("tree" === this.rowHierarchyType && this.initTreeHierarchyState(), this.userPagination) {
                    this.pagination.totalCount = this._sourceLength;
                    const {perPageCount: perPageCount, currentPage: currentPage} = this.pagination;
                    index < perPageCount * (currentPage || 0) + perPageCount && this.updatePagerData();
                } else this.pagination.perPageCount = this._sourceLength, this.pagination.totalCount = this._sourceLength, 
                this.updatePagerData();
                (null === (_a = this.dataSourceObj) || void 0 === _a ? void 0 : _a.added) && this.dataSourceObj.added(index, 1);
            }
            return;
        }
        const rawRecords = this._getRawRecordsArray();
        if (!rawRecords) return;
        const viewInsertIndex = this._normalizeInsertIndex(index, this.records.length), rawInsertIndex = this._hasFilterInEffect() ? this._mapViewInsertIndexToRawInsertIndex(rawRecords, viewInsertIndex) : this._normalizeInsertIndex(viewInsertIndex, rawRecords.length);
        rawRecords.splice(rawInsertIndex, 0, record), this.beforeChangedRecordsMap.clear(), 
        this.sortedIndexMap.clear(), this.updateFilterRules(null === (_b = this.dataConfig) || void 0 === _b ? void 0 : _b.filterRules), 
        (null === (_c = this.dataSourceObj) || void 0 === _c ? void 0 : _c.added) && this.dataSourceObj.added(rawInsertIndex, 1);
    }
    addRecords(recordArr, index, syncToOriginalRecords = !1) {
        var _a, _b, _c;
        if (!syncToOriginalRecords) {
            if (Array.isArray(this.records)) {
                if (Array.isArray(recordArr)) {
                    this.records.splice(index, 0, ...recordArr), this.adjustBeforeChangedRecordsMap(index, recordArr.length);
                    for (let i = 0; i < recordArr.length; i++) this.currentIndexedData.push(this.currentIndexedData.length);
                    this._sourceLength += recordArr.length;
                    for (let i = 0; i < this.fieldAggregators.length; i++) for (let j = 0; j < recordArr.length; j++) this.fieldAggregators[i].push(recordArr[j]);
                }
                if (this.userPagination) {
                    this.pagination.totalCount = this._sourceLength;
                    const {perPageCount: perPageCount, currentPage: currentPage} = this.pagination;
                    index < perPageCount * (currentPage || 0) + perPageCount && this.updatePagerData();
                } else this.pagination.perPageCount = this._sourceLength, this.pagination.totalCount = this._sourceLength, 
                this.updatePagerData();
                (null === (_a = this.dataSourceObj) || void 0 === _a ? void 0 : _a.added) && this.dataSourceObj.added(index, recordArr.length);
            }
            return;
        }
        const rawRecords = this._getRawRecordsArray();
        if (!rawRecords || !Array.isArray(recordArr) || 0 === recordArr.length) return;
        const viewInsertIndex = this._normalizeInsertIndex(index, this.records.length), rawInsertIndex = this._hasFilterInEffect() ? this._mapViewInsertIndexToRawInsertIndex(rawRecords, viewInsertIndex) : this._normalizeInsertIndex(viewInsertIndex, rawRecords.length);
        rawRecords.splice(rawInsertIndex, 0, ...recordArr), this.beforeChangedRecordsMap.clear(), 
        this.sortedIndexMap.clear(), this.updateFilterRules(null === (_b = this.dataConfig) || void 0 === _b ? void 0 : _b.filterRules), 
        (null === (_c = this.dataSourceObj) || void 0 === _c ? void 0 : _c.added) && this.dataSourceObj.added(rawInsertIndex, recordArr.length);
    }
    addRecordForSorted(record) {
        Array.isArray(this.records) && (this.beforeChangedRecordsMap.clear(), this.records.push(record), 
        this.currentIndexedData.push(this.currentIndexedData.length), this._sourceLength += 1, 
        this.sortedIndexMap.clear(), this.userPagination || (this.pagination.perPageCount = this._sourceLength, 
        this.pagination.totalCount = this._sourceLength));
    }
    addRecordsForSorted(recordArr) {
        if (Array.isArray(this.records)) {
            if (this.beforeChangedRecordsMap.clear(), Array.isArray(recordArr)) {
                this.records.push(...recordArr);
                for (let i = 0; i < recordArr.length; i++) this.currentIndexedData.push(this.currentIndexedData.length);
                this._sourceLength += recordArr.length, this.sortedIndexMap.clear();
            }
            this.userPagination || (this.pagination.perPageCount = this._sourceLength, this.pagination.totalCount = this._sourceLength);
        }
    }
    adjustBeforeChangedRecordsMap(insertIndex, insertCount, type = "add") {
        const delta = "add" === type ? insertCount : -insertCount, numericKeys = [];
        this.beforeChangedRecordsMap.forEach(((_, key) => {
            const numKey = Number(key);
            Number.isInteger(numKey) && numKey.toString() === key && numKey >= insertIndex && numericKeys.push(numKey);
        })), numericKeys.sort(((a, b) => "add" === type ? b - a : a - b));
        for (let i = 0; i < numericKeys.length; i++) {
            const key = numericKeys[i], record = this.beforeChangedRecordsMap.get(key.toString());
            this.beforeChangedRecordsMap.delete(key.toString()), this.beforeChangedRecordsMap.set((key + delta).toString(), record);
        }
    }
    deleteRecords(recordIndexs, syncToOriginalRecords = !1) {
        var _a, _b, _c;
        if (!syncToOriginalRecords) {
            if (Array.isArray(this.records)) {
                const realDeletedRecordIndexs = [], recordIndexsMaxToMin = recordIndexs.sort(((a, b) => b - a));
                for (let index = 0; index < recordIndexsMaxToMin.length; index++) {
                    const recordIndex = recordIndexsMaxToMin[index];
                    if (recordIndex >= this._sourceLength || recordIndex < 0) continue;
                    this.adjustBeforeChangedRecordsMap(recordIndex, 1, "delete"), realDeletedRecordIndexs.push(recordIndex);
                    const deletedRecord = this.records[recordIndex];
                    for (let i = 0; i < this.fieldAggregators.length; i++) this.fieldAggregators[i].deleteRecord(deletedRecord);
                    this.records.splice(recordIndex, 1), this.currentIndexedData.pop(), this._sourceLength -= 1;
                }
                return this.userPagination || (this.pagination.perPageCount = this._sourceLength, 
                this.pagination.totalCount = this._sourceLength), this.updatePagerData(), (null === (_a = this.dataSourceObj) || void 0 === _a ? void 0 : _a.deleted) && this.dataSourceObj.deleted(realDeletedRecordIndexs), 
                realDeletedRecordIndexs;
            }
            return [];
        }
        const rawRecords = this._getRawRecordsArray();
        if (!rawRecords || !Array.isArray(this.records)) return [];
        const realDeletedRecordIndexs = [], recordIndexsMaxToMin = recordIndexs.slice().sort(((a, b) => b - a)), rawDeletedIndexs = [];
        for (let index = 0; index < recordIndexsMaxToMin.length; index++) {
            const viewIndex = recordIndexsMaxToMin[index];
            if (viewIndex >= this.records.length || viewIndex < 0) continue;
            const deletedRecord = this.records[viewIndex], rawIndex = rawRecords.indexOf(deletedRecord);
            rawIndex >= 0 && (rawRecords.splice(rawIndex, 1), rawDeletedIndexs.push(rawIndex)), 
            realDeletedRecordIndexs.push(viewIndex);
        }
        return this.beforeChangedRecordsMap.clear(), this.sortedIndexMap.clear(), this.updateFilterRules(null === (_b = this.dataConfig) || void 0 === _b ? void 0 : _b.filterRules), 
        (null === (_c = this.dataSourceObj) || void 0 === _c ? void 0 : _c.deleted) && this.dataSourceObj.deleted(rawDeletedIndexs), 
        realDeletedRecordIndexs;
    }
    deleteRecordsForSorted(recordIndexs) {
        if (Array.isArray(this.records)) {
            const recordIndexsMaxToMin = recordIndexs.sort(((a, b) => b - a));
            for (let index = 0; index < recordIndexsMaxToMin.length; index++) {
                const recordIndex = recordIndexsMaxToMin[index];
                if (recordIndex >= this._sourceLength || recordIndex < 0) continue;
                const rawIndex = this.currentIndexedData[recordIndex];
                this.records.splice(rawIndex, 1), this._sourceLength -= 1;
            }
            this.sortedIndexMap.clear(), this.userPagination || (this.pagination.perPageCount = this._sourceLength, 
            this.pagination.totalCount = this._sourceLength), this.beforeChangedRecordsMap.clear();
        }
    }
    updateRecords(records, recordIndexs, syncToOriginalRecords = !1) {
        var _a;
        if (!syncToOriginalRecords) {
            const realDeletedRecordIndexs = [];
            for (let index = 0; index < recordIndexs.length; index++) {
                const recordIndex = recordIndexs[index];
                if (Array.isArray(recordIndex)) this.beforeChangedRecordsMap.delete(recordIndex.toString()), 
                realDeletedRecordIndexs.push(recordIndex), recordIndex.slice(0, -1).reduce(((acc, key) => (void 0 === acc[key] && (acc[key] = {}), 
                acc[key].children)), this.records)[recordIndex[recordIndex.length - 1]] = records[index]; else {
                    if (recordIndex >= this._sourceLength || recordIndex < 0) continue;
                    this.beforeChangedRecordsMap.delete(recordIndex.toString()), realDeletedRecordIndexs.push(recordIndex);
                    for (let i = 0; i < this.fieldAggregators.length; i++) this.fieldAggregators[i].updateRecord(this.records[recordIndex], records[index]);
                    this.records[recordIndex] = records[index];
                }
            }
            return this.userPagination && this.updatePagerData(), realDeletedRecordIndexs;
        }
        const rawRecords = this._getRawRecordsArray();
        if (!rawRecords || !Array.isArray(this.records)) return [];
        const realUpdatedIndexs = [];
        for (let index = 0; index < recordIndexs.length; index++) {
            const recordIndex = recordIndexs[index];
            if (Array.isArray(recordIndex)) this.beforeChangedRecordsMap.delete(recordIndex.toString()), 
            realUpdatedIndexs.push(recordIndex), recordIndex.slice(0, -1).reduce(((acc, key) => (void 0 === acc[key] && (acc[key] = {}), 
            acc[key].children)), rawRecords)[recordIndex[recordIndex.length - 1]] = records[index]; else {
                if (recordIndex >= this.records.length || recordIndex < 0) continue;
                const oldRecord = this.records[recordIndex], rawIndex = rawRecords.indexOf(oldRecord);
                rawIndex >= 0 && (rawRecords[rawIndex] = records[index]), realUpdatedIndexs.push(recordIndex);
            }
        }
        return this.beforeChangedRecordsMap.clear(), this.sortedIndexMap.clear(), this.updateFilterRules(null === (_a = this.dataConfig) || void 0 === _a ? void 0 : _a.filterRules), 
        realUpdatedIndexs;
    }
    updateRecordsForSorted(records, recordIndexs) {
        const realDeletedRecordIndexs = [];
        for (let index = 0; index < recordIndexs.length; index++) {
            const recordIndex = recordIndexs[index];
            if (recordIndex >= this._sourceLength || recordIndex < 0) continue;
            const rawIndex = this.currentIndexedData[recordIndex];
            if ("number" != typeof rawIndex) return;
            this.beforeChangedRecordsMap.delete(rawIndex.toString()), realDeletedRecordIndexs.push(recordIndex), 
            this.records[rawIndex] = records[index];
        }
        this.sortedIndexMap.clear();
    }
    sort(states) {
        states = (Array.isArray(states) ? states : [ states ]).filter((state => {
            const column = this.columns.find((obj => obj.field === state.field));
            return !1 !== (null == column ? void 0 : column.sort) && "normal" !== state.order;
        })), this.lastSortStates = states;
        let filedMapArray = states.map((state => this.sortedIndexMap.get(null == state ? void 0 : state.field) || {
            asc: [],
            desc: [],
            normal: []
        })), orderedData = null;
        if (filedMapArray.length > 0 && (orderedData = states.reduce(((data, state, index) => {
            var _a;
            const currentData = null === (_a = filedMapArray[index]) || void 0 === _a ? void 0 : _a[state.order];
            return currentData && currentData.length > 0 ? currentData : data;
        }), null), orderedData && orderedData.length > 0)) return this.currentIndexedData = orderedData, 
        this.updatePagerData(), void this.fireListeners(EVENT_TYPE.CHANGE_ORDER, null);
        const sortedIndexArray = Array.from({
            length: this._sourceLength
        }, ((_, i) => i));
        if (sortedIndexArray.sort(((indexA, indexB) => {
            const recordA = this.getOriginalRecord(indexA), recordB = this.getOriginalRecord(indexB), isEmptyA = null == recordA || "object" == typeof recordA && 0 === Object.keys(recordA).length, isEmptyB = null == recordB || "object" == typeof recordB && 0 === Object.keys(recordB).length;
            return states.reduce(((result, state) => {
                if (0 !== result) return result;
                if ("asc" === state.order || "desc" === state.order) {
                    if (isEmptyA && !isEmptyB) return 1;
                    if (!isEmptyA && isEmptyB) return -1;
                    if (isEmptyA && isEmptyB) return indexA - indexB;
                } else if (isEmptyA || isEmptyB) return indexA - indexB;
                return (state.orderFn || ("desc" !== state.order ? (v1, v2) => v1 === v2 ? 0 : v1 > v2 ? 1 : -1 : (v1, v2) => v1 === v2 ? 0 : v1 < v2 ? 1 : -1))(this.getOriginalField(indexA, state.field), this.getOriginalField(indexB, state.field), state.order);
            }), 0);
        })), this.currentIndexedData = sortedIndexArray, this.hierarchyExpandLevel && "tree" === this.rowHierarchyType) {
            let nodeLength = sortedIndexArray.length;
            for (let i = 0; i < nodeLength; i++) {
                const record = this.getOriginalRecord(sortedIndexArray[i]), subNodeLength = this.pushChildrenNode(sortedIndexArray[i], record.hierarchyState, this.getOriginalRecord(sortedIndexArray[i]));
                nodeLength += subNodeLength, i += subNodeLength;
            }
        }
        if (!filedMapArray.length) {
            filedMapArray = states.map((() => ({
                asc: [],
                desc: [],
                normal: []
            })));
            for (let index = 0; index < states.length; index++) this.sortedIndexMap.set(states[index].field, filedMapArray[index]);
        }
        states.forEach(((state, index) => {
            filedMapArray[index][state.order] = sortedIndexArray.slice();
        })), this.updatePagerData(), this.fireListeners(EVENT_TYPE.CHANGE_ORDER, null);
    }
    setSortedIndexMap(field, filedMap) {
        this.sortedIndexMap.set(field, filedMap);
    }
    clearFilteredChildren(record) {
        var _a, _b;
        record.filteredChildren = void 0;
        for (let i = 0; i < (null !== (_b = null === (_a = record.children) || void 0 === _a ? void 0 : _a.length) && void 0 !== _b ? _b : 0); i++) this.clearFilteredChildren(record.children[i]);
    }
    filterRecord(record) {
        var _a, _b, _c;
        let isReserved = !0;
        for (let i = 0; i < (null === (_a = this.dataConfig.filterRules) || void 0 === _a ? void 0 : _a.length); i++) {
            const filterRule = null === (_b = this.dataConfig) || void 0 === _b ? void 0 : _b.filterRules[i];
            if (filterRule.filterKey) {
                const filterValue = record[filterRule.filterKey];
                if (-1 === filterRule.filteredValues.indexOf(filterValue)) {
                    isReserved = !1;
                    break;
                }
            } else if (!(null === (_c = filterRule.filterFunc) || void 0 === _c ? void 0 : _c.call(filterRule, record))) {
                isReserved = !1;
                break;
            }
        }
        return isReserved;
    }
    updateFilterRulesForSorted(filterRules) {
        var _a, _b, _c;
        this.lastFilterRules = this.dataConfig.filterRules, this.dataConfig.filterRules = filterRules, 
        this._source = this.processRecords(null !== (_b = null === (_a = this.dataSourceObj) || void 0 === _a ? void 0 : _a.records) && void 0 !== _b ? _b : this.dataSourceObj), 
        this._sourceLength = (null === (_c = this._source) || void 0 === _c ? void 0 : _c.length) || 0, 
        this.sortedIndexMap.clear(), this.currentIndexedData = Array.from({
            length: this._sourceLength
        }, ((_, i) => i)), "tree" === this.rowHierarchyType && this.initTreeHierarchyState(), 
        this.userPagination || (this.pagination.perPageCount = this._sourceLength, this.pagination.totalCount = this._sourceLength);
    }
    updateFilterRules(filterRules, onFilterRecordsEnd) {
        var _a, _b, _c;
        this.lastFilterRules = this.dataConfig.filterRules, this.dataConfig.filterRules = filterRules, 
        this._source = this.processRecords(null !== (_b = null === (_a = this.dataSourceObj) || void 0 === _a ? void 0 : _a.records) && void 0 !== _b ? _b : this.dataSourceObj), 
        onFilterRecordsEnd && onFilterRecordsEnd(this._source), this._sourceLength = (null === (_c = this._source) || void 0 === _c ? void 0 : _c.length) || 0, 
        this.currentIndexedData = Array.from({
            length: this._sourceLength
        }, ((_, i) => i)), this.userPagination || (this.pagination.perPageCount = this._sourceLength, 
        this.pagination.totalCount = this._sourceLength, "tree" === this.rowHierarchyType && this.initTreeHierarchyState()), 
        this.updatePagerData();
    }
    clearSortedIndexMap() {
        this.lastSortStates && this.lastSortStates.length > 0 && this.sortedIndexMap.forEach(((sortMap, key) => {
            this.lastSortStates.some((state => state.field === key)) ? this.lastSortStates.forEach((state => {
                "asc" === state.order ? (sortMap.desc = [], sortMap.normal = []) : "desc" === state.order ? (sortMap.asc = [], 
                sortMap.normal = []) : (sortMap.asc = [], sortMap.desc = []);
            })) : this.sortedIndexMap.delete(key);
        }));
    }
    get sourceLength() {
        return this._sourceLength;
    }
    set sourceLength(sourceLen) {
        this._sourceLength !== sourceLen && (this._sourceLength = sourceLen, this.fireListeners(EVENT_TYPE.SOURCE_LENGTH_UPDATE, this._sourceLength));
    }
    get length() {
        return this.currentPagerIndexedData.length;
    }
    get dataSource() {
        return this;
    }
    get currentPagerIndexedData() {
        return this._currentPagerIndexedData.length > 0 ? this._currentPagerIndexedData : [];
    }
    release() {
        var _a;
        null === (_a = super.release) || void 0 === _a || _a.call(this), this.lastFilterRules = null, 
        this.clearSortedMap(), this.clearCurrentIndexedData(), this.currentPagerIndexedData.length = 0;
    }
    clearSortedMap() {
        this.currentIndexedData && (this.currentIndexedData.length = 0), this.currentIndexedData = null, 
        this.sortedIndexMap.forEach((item => {
            item.asc && (item.asc.length = 0), item.desc && (item.desc.length = 0);
        })), this.sortedIndexMap.clear();
    }
    clearCurrentIndexedData() {
        this.currentIndexedData = null, this.currentPagerIndexedData.length = 0;
    }
    getOriginalRecord(dataIndex) {
        let data;
        return data = this.dataSourceObj.records ? Array.isArray(dataIndex) ? getValueFromDeepArray(this.records, dataIndex) : this.records[dataIndex] : this._get(dataIndex), 
        getValue(data, (val => {
            this.recordPromiseCallBack(dataIndex, val);
        }));
    }
    getRawRecord(dataIndex) {
        var _a, _b;
        if (null === (_a = this.beforeChangedRecordsMap) || void 0 === _a ? void 0 : _a.has(dataIndex.toString())) return null === (_b = this.beforeChangedRecordsMap) || void 0 === _b ? void 0 : _b.get(dataIndex.toString());
        let data;
        return data = this.dataSourceObj.records ? Array.isArray(dataIndex) ? getValueFromDeepArray(this.records, dataIndex) : this.records[dataIndex] : this._get(dataIndex), 
        getValue(data, (val => {
            this.recordPromiseCallBack(dataIndex, val);
        }));
    }
    getOriginalField(index, field, col, row, table) {
        if (null === field) return;
        return getField(this.getOriginalRecord(index), field, col, row, table, (val => {
            this.fieldPromiseCallBack(index, field, val);
        }));
    }
    getRawFieldData(index, field, col, row, table) {
        if (null === field) return;
        return getField(this.getRawRecord(index), field, col, row, table, (val => {
            this.fieldPromiseCallBack(index, field, val);
        }));
    }
    hasOriginalField(index, field) {
        if (null === field) return !1;
        if ("function" == typeof field) return !0;
        const record = this.getOriginalRecord(index);
        return Boolean(record && field in record);
    }
    fieldPromiseCallBack(_index, _field, _value) {}
    recordPromiseCallBack(_index, _record) {}
    canChangeOrder(sourceIndex, targetIndex) {
        var _a;
        if (null === (_a = this.dataSourceObj) || void 0 === _a ? void 0 : _a.canChangeOrder) return this.dataSourceObj.canChangeOrder(sourceIndex, targetIndex);
        if (this.hasHierarchyStateExpand) {
            let sourceIndexs = this.currentPagerIndexedData[sourceIndex], targetIndexs = this.currentPagerIndexedData[targetIndex];
            if (sourceIndexs = Array.isArray(sourceIndexs) ? [ ...sourceIndexs ] : [ sourceIndexs ], 
            targetIndexs = Array.isArray(targetIndexs) ? [ ...targetIndexs ] : [ targetIndexs ], 
            targetIndex > sourceIndex && targetIndexs.length > sourceIndexs.length) {
                let targetNextIndexs = this.currentPagerIndexedData[targetIndex + 1];
                targetNextIndexs = Array.isArray(targetNextIndexs) ? [ ...targetNextIndexs ] : [ targetNextIndexs ], 
                targetNextIndexs.length < targetIndexs.length && targetIndexs.splice(targetIndexs.length - 1, 1);
            }
            if (sourceIndexs.length === targetIndexs.length) {
                for (let i = 0; i <= sourceIndexs.length - 2; i++) if (sourceIndexs[i] !== targetIndexs[i]) return !1;
                return !0;
            }
            return !1;
        }
        return !0;
    }
    changeOrder(sourceIndex, targetIndex) {
        var _a, _b, _c;
        if (null === (_a = this.dataSourceObj) || void 0 === _a ? void 0 : _a.changeOrder) this.dataSourceObj.changeOrder(sourceIndex, targetIndex); else if (!(null === (_b = this.lastSortStates) || void 0 === _b ? void 0 : _b.some((state => "asc" === state.order || "desc" === state.order))) && this.canChangeOrder(sourceIndex, targetIndex)) if (this.hasHierarchyStateExpand) {
            let sourceI, targetI, sourceIndexs = this.currentPagerIndexedData[sourceIndex], targetIndexs = this.currentPagerIndexedData[targetIndex];
            if (sourceIndexs = Array.isArray(sourceIndexs) ? [ ...sourceIndexs ] : [ sourceIndexs ], 
            targetIndexs = Array.isArray(targetIndexs) ? [ ...targetIndexs ] : [ targetIndexs ], 
            sourceIndexs.length > 1 || targetIndexs.length > 1) {
                if (targetIndex > sourceIndex && targetIndexs.length > sourceIndexs.length) {
                    let targetNextIndexs = this.currentPagerIndexedData[targetIndex + 1];
                    targetNextIndexs = Array.isArray(targetNextIndexs) ? [ ...targetNextIndexs ] : [ targetNextIndexs ], 
                    targetNextIndexs.length < targetIndexs.length && targetIndexs.splice(targetIndexs.length - 1, 1);
                }
                if (sourceI = sourceIndexs.splice(sourceIndexs.length - 1, 1)[0], targetI = targetIndexs.splice(targetIndexs.length - 1, 1)[0], 
                sourceIndexs.length >= 1) {
                    const parent = this.getOriginalRecord(sourceIndexs);
                    if (parent) {
                        const sourceIds = parent.filteredChildren ? parent.filteredChildren.splice(sourceI, 1) : parent.children.splice(sourceI, 1);
                        sourceIds.unshift(targetI, 0), Array.prototype.splice.apply(null !== (_c = parent.filteredChildren) && void 0 !== _c ? _c : parent.children, sourceIds);
                    }
                } else {
                    const sourceIds = this.records.splice(sourceI, 1);
                    sourceIds.unshift(targetI, 0), Array.prototype.splice.apply(this.records, sourceIds);
                }
            } else this.exchangeRecordData(sourceIndex, targetIndex);
            this.restoreTreeHierarchyState(), this.updatePagerData();
        } else this.exchangeRecordData(sourceIndex, targetIndex);
    }
    exchangeRecordData(sourceIndex, targetIndex) {
        const sourceI = this.getRecordIndexPaths(sourceIndex), targetI = this.getRecordIndexPaths(targetIndex), records = this.records.splice(sourceI, 1);
        records.unshift(targetI, 0), Array.prototype.splice.apply(this.records, records);
    }
    restoreTreeHierarchyState() {
        var _a, _b;
        if (this.hierarchyExpandLevel) {
            for (let i = 0; i < this._sourceLength; i++) {
                const nodeData = this.getOriginalRecord(i);
                if (!nodeData) continue;
                (null !== (_a = nodeData.filteredChildren) && void 0 !== _a ? _a : nodeData.children) && !nodeData.hierarchyState && (nodeData.hierarchyState = HierarchyState.collapse);
            }
            this.currentIndexedData = Array.from({
                length: this._sourceLength
            }, ((_, i) => i));
            let nodeLength = this._sourceLength;
            for (let i = 0; i < nodeLength; i++) {
                const indexKey = this.currentIndexedData[i], nodeData = this.getOriginalRecord(indexKey);
                if (!nodeData) continue;
                const children = null !== (_b = nodeData.filteredChildren) && void 0 !== _b ? _b : nodeData.children;
                if ((null == children ? void 0 : children.length) > 0 && nodeData.hierarchyState === HierarchyState.expand) {
                    this.hasHierarchyStateExpand = !0;
                    const childrenLength = this.restoreChildrenNodeHierarchy(indexKey, nodeData);
                    i += childrenLength, nodeLength += childrenLength;
                } else !0 === nodeData.children && !nodeData.hierarchyState && (nodeData.hierarchyState = HierarchyState.collapse);
            }
        }
    }
    restoreChildrenNodeHierarchy(indexKey, nodeData) {
        var _a, _b;
        let childTotalLength = 0;
        const children = null !== (_a = nodeData.filteredChildren) && void 0 !== _a ? _a : nodeData.children, nodeLength = null !== (_b = null == children ? void 0 : children.length) && void 0 !== _b ? _b : 0;
        for (let j = 0; j < nodeLength; j++) {
            nodeData.hierarchyState === HierarchyState.expand && (childTotalLength += 1);
            const childNodeData = children[j], childIndexKey = Array.isArray(indexKey) ? indexKey.concat(j) : [ indexKey, j ];
            nodeData.hierarchyState === HierarchyState.expand && this.currentIndexedData.splice(this.currentIndexedData.indexOf(indexKey) + childTotalLength, 0, childIndexKey), 
            childTotalLength += this.restoreChildrenNodeHierarchy(childIndexKey, childNodeData);
        }
        return childTotalLength;
    }
    _setNodeStateRecursive(node, targetState) {
        var _a;
        if (!node) return;
        const children = null !== (_a = node.filteredChildren) && void 0 !== _a ? _a : node.children;
        if (children && (Array.isArray(children) ? children.length > 0 : !0 === children) && (node.hierarchyState = targetState), 
        children && Array.isArray(children)) for (const child of children) this._setNodeStateRecursive(child, targetState);
    }
    expandAllNodes() {
        if (Array.isArray(this._source)) {
            for (const rootNode of this._source) this._setNodeStateRecursive(rootNode, HierarchyState.expand);
            this.hasHierarchyStateExpand = !0, this.clearSortedIndexMap(), this.restoreTreeHierarchyState(), 
            this.lastSortStates && this.lastSortStates.length > 0 ? this.sort(this.lastSortStates) : this.updatePagerData();
        }
    }
    collapseAllNodes() {
        if (Array.isArray(this._source)) {
            for (const rootNode of this._source) this._setNodeStateRecursive(rootNode, HierarchyState.collapse);
            this.clearSortedIndexMap(), this.restoreTreeHierarchyState(), this.lastSortStates && this.lastSortStates.length > 0 ? this.sort(this.lastSortStates) : this.updatePagerData();
        }
    }
}

DataSource.EMPTY = new DataSource({
    get() {},
    length: 0
});

export function getValueFromDeepArray(array, index) {
    var _a;
    let result = array;
    for (let i = 0; i < index.length; i++) {
        const currentIdx = index[i];
        if (!result[currentIdx]) return;
        result = result[currentIdx];
        const children = null !== (_a = result.filteredChildren) && void 0 !== _a ? _a : null == result ? void 0 : result.children;
        children && i + 1 < index.length && (result = children);
    }
    return result;
}

export function sortRecordIndexs(recordIndexs, sort) {
    return recordIndexs.sort(((a, b) => {
        var _a, _b;
        isNumber(a) && (a = [ a ]), isNumber(b) && (b = [ b ]);
        const length = Math.max(a.length, b.length);
        for (let i = 0; i < length; i++) {
            const aa = null !== (_a = a[i]) && void 0 !== _a ? _a : -1, bb = null !== (_b = b[i]) && void 0 !== _b ? _b : -1;
            if (aa !== bb) return 1 === sort ? aa - bb : bb - aa;
        }
        return 0;
    }));
}
//# sourceMappingURL=DataSource.js.map