"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.NestedTableState = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _bexCore = require("@wix/bex-core");
var _ToolbarCollectionState = require("../ToolbarCollectionState");
var _TableState = require("../TableState");
var _NestedTableNestedModeState = require("./NestedTableNestedModeState");
var _NestedTableFlatModeState = require("./NestedTableFlatModeState");
var _NestedCollectionFetchAllState = require("./NestedCollectionFetchAllState");
var _mobx = require("mobx");
var _createNestedOptimisticActions = require("./createNestedOptimisticActions");
class NestedTableState {
  constructor(params) {
    (0, _defineProperty2.default)(this, "container", void 0);
    (0, _defineProperty2.default)(this, "reportBi", void 0);
    (0, _defineProperty2.default)(this, "toolbar", void 0);
    (0, _defineProperty2.default)(this, "tableState", void 0);
    (0, _defineProperty2.default)(this, "mainColumn", void 0);
    (0, _defineProperty2.default)(this, "options", void 0);
    (0, _defineProperty2.default)(this, "initTask", new _bexCore.TaskState());
    (0, _defineProperty2.default)(this, "levels", void 0);
    (0, _defineProperty2.default)(this, "rootNodeCollection", void 0);
    (0, _defineProperty2.default)(this, "query", void 0);
    (0, _defineProperty2.default)(this, "nested", void 0);
    (0, _defineProperty2.default)(this, "flat", void 0);
    (0, _defineProperty2.default)(this, "sequences", new Map());
    this.container = params.container;
    this.query = new _bexCore.QueryState({
      filters: params.filters || {}
    });
    this.levels = params.levels.map((level, i) => ({
      ...level,
      depth: i
    }));
    const fetchAllLimit = params.fetchAllLimit ?? params.fetchAllThreshold;
    this.options = {
      fetchAllThreshold: fetchAllLimit ?? 1000,
      expandAllThreshold: params.expandAllThreshold ?? fetchAllLimit ?? 1000
    };
    this.mainColumn = params.mainColumn;
    const rootLevelDescriptor = this.levels[0];
    if (rootLevelDescriptor == null) {
      throw new Error('NestedTableState must have at least one level');
    }
    const nestedOptimisticActionsState = {
      parentId: '',
      sequences: this.sequences,
      query: this.query,
      levelDescriptor: rootLevelDescriptor
    };
    this.rootNodeCollection = rootLevelDescriptor.createCollection(nestedOptimisticActionsState);
    (0, _createNestedOptimisticActions.createNestedOptimisticActions)(this.container, this.rootNodeCollection.collection, nestedOptimisticActionsState);
    const {
      collection
    } = this.rootNodeCollection;
    (0, _bexCore.syncWithSharedQuery)(collection.query, this.query);
    this.reportBi = reportProps => {
      const {
        isFetchAllAborted
      } = this;
      this.container.reportBi({
        ...reportProps,
        params: {
          ...reportProps.params,
          ...(isFetchAllAborted != null && {
            componentStatus: isFetchAllAborted ? 'All items collapsed' : 'All items expanded'
          })
        }
      });
    };
    this.toolbar = new _ToolbarCollectionState.ToolbarCollectionState({
      collection: this.rootNodeCollection.collection,
      container: params.container,
      componentType: 'NestedTable',
      reportBi: this.reportBi
    });
    this.toolbar.setNewColumns(params.columns.map(column => ({
      ...column,
      render: () => null
    })));
    this.tableState = new _TableState.TableState({
      collection: this.rootNodeCollection.collection,
      container: params.container,
      toolbar: this.toolbar
    });
    this.nested = new _NestedTableNestedModeState.NestedTableNestedModeState({
      wrapper: this,
      reportBi: this.reportBi
    });
    this.flat = new _NestedTableFlatModeState.NestedTableFlatModeState({
      wrapper: this
    });
  }
  get nestedMode() {
    return this.nested;
  }
  get flatMode() {
    return this.flat;
  }
  getNode(key) {
    return this.nested.getNode(key);
  }
  getRootNode() {
    return this.nested.root;
  }

  /**
   * Get all the nodes in the table
   */
  getAllNodes() {
    return this.nested.getAllNodes();
  }
  get isFetchAllAborted() {
    return this.nested.isFetchAllAborted;
  }
  get expandAll() {
    return this.nested.expandAll;
  }
  get nestedCollection() {
    return this.nested.nestedCollection;
  }
  _attemptFetchAllAndPopulateCache() {
    const initTask = new _bexCore.TaskState();
    return {
      initTask,
      init: ({
        invalidate
      } = {
        invalidate: false
      }) => {
        initTask.runOnce(async () => {
          const fetchAllState = new _NestedCollectionFetchAllState.NestedCollectionFetchAllState({
            options: this.options,
            query: this.nested.query,
            nestedCollectionState: this.nested.nestedCollection
          });
          const disposers = [fetchAllState.init({
            invalidate
          })];
          try {
            await fetchAllState.initTask.status.promise;
          } finally {
            disposers.forEach(d => d());
          }
        });
        return () => {};
      }
    };
  }
  refreshAll({
    invalidate = true
  } = {}) {
    const initTask = this.isFlatMode ? this.flat.initTask : this.nested.initTask;
    initTask.reset();
    initTask.runOnce(async () => {
      const fetchAll = this._attemptFetchAllAndPopulateCache();
      fetchAll.init({
        invalidate
      });
      await fetchAll.initTask.status.promise;
      await (this.isFlatMode ? this.flatMode._refreshAll() : this.nestedMode.root._refreshAll());
      this.rootNodeCollection.collection.query.events.emit('refresh');
    });
  }
  get isFlatMode() {
    return !!this.query.search.value;
  }
  _addFilterListeners() {
    return Object.values(this.query.filtersEntries).map(([_, filter]) => {
      return (0, _bexCore.addEventListener)(filter.events, 'refresh', () => {
        this.refreshAll({
          invalidate: false
        });
      });
    });
  }
  init() {
    const {
      initTask,
      tableState,
      query
    } = this;
    const disposers = [query.init({
      skipFilterListeners: true
    }), ...this._addFilterListeners(), (0, _mobx.reaction)(() => this.isFlatMode, isFlatMode => {
      const {
        query: {
          _fields
        }
      } = this;
      if (isFlatMode) {
        _fields.add('breadcrumbs');
      } else {
        _fields.delete('breadcrumbs');
      }
    }, {
      fireImmediately: true
    }), tableState.init({
      featuresInitializers: [],
      skipFilterListeners: true
    })];
    initTask.runOnce(async () => {
      tableState.initTask.runOnce();
      await tableState.initTask.status.promise;
    });
    return () => {
      initTask.reset();
      disposers.forEach(d => d());
    };
  }
}
exports.NestedTableState = NestedTableState;
//# sourceMappingURL=NestedTableState.js.map