import { NestedCollectionFetchAllCollectionState } from './NestedCollectionFetchAllCollectionState';
import { TaskState } from '@wix/bex-core';
import { EventEmitter } from 'events';
import { action, computed, makeObservable } from 'mobx';
export class NestedCollectionFetchAllState {
    constructor(params) {
        this.events = new EventEmitter();
        this.initTask = new TaskState();
        this.isFetchAllAborted = false;
        const { nestedCollectionState } = params;
        this.options = params.options;
        this.query = params.query;
        const { levels } = nestedCollectionState;
        this.nestedCollectionState = nestedCollectionState;
        this.fetchedAllPromise = new Promise((resolve) => {
            this.events.once('fetchAllAbortSignal', resolve);
        });
        this.collections = levels.map((levelDescriptor) => {
            return new NestedCollectionFetchAllCollectionState({
                levelDescriptor,
                fetchAllState: this,
            });
        });
        makeObservable(this, {
            total: computed,
            _setInitialExpandAllByThreshold: action,
        });
    }
    init({ invalidate } = { invalidate: false }) {
        const { initTask, fetchedAllPromise, nestedCollectionState, collections } = this;
        if (invalidate) {
            collections.forEach((c) => {
                c.collection.invalidate();
            });
        }
        const disposers = [...collections.map((c) => c.init())];
        initTask.runOnce(async () => {
            collections.forEach(({ initTask }) => {
                initTask.runOnce();
            });
            const collectionsFetchAllPromise = Promise.all(collections.map((c) => c.initTask.status.promise));
            await Promise.race([collectionsFetchAllPromise, fetchedAllPromise]);
            nestedCollectionState.isFetchAllAborted = this.isFetchAllAborted;
            nestedCollectionState._fetchAllTotal = this.total;
            if (this.isFetchAllAborted) {
                nestedCollectionState.expandAll = false; // override expandAll to false if fetchAll was aborted
            }
            else {
                this._setInitialExpandAllByThreshold();
                this._populateParentIdRequestsCache();
            }
        });
        return () => {
            disposers.forEach((d) => d());
        };
    }
    _setInitialExpandAllByThreshold() {
        const { nestedCollectionState, total, options: { expandAllThreshold }, } = this;
        nestedCollectionState.total = total;
        nestedCollectionState.expandAll = total <= expandAllThreshold;
    }
    _populateParentIdRequestsCache() {
        const { uniqueCollections } = this;
        uniqueCollections.forEach((c, index, arr) => {
            c._populateCache(arr[index + 1]);
        });
    }
    get uniqueCollections() {
        const { collections } = this;
        return Array.from(collections
            .reduce((map, c) => {
            map.set(c.collection.getCurrentQuery(), c);
            return map;
        }, new Map())
            .values());
    }
    get total() {
        const { uniqueCollections } = this;
        return uniqueCollections.reduce((acc, c) => {
            return acc + c.collection.result.total;
        }, 0);
    }
    _otherLevelSameCollectionExists(collection) {
        const { collections } = this;
        return collections.some((other) => {
            return (other !== collection &&
                other.collection.getCurrentQuery() ===
                    collection.collection.getCurrentQuery());
        });
    }
}
//# sourceMappingURL=NestedCollectionFetchAllState.js.map