"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.CustomColumnsState = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _bexCore = require("@wix/bex-core");
var _mobx = require("mobx");
var _CustomColumnsHistoryState = require("./CustomColumnsHistoryState");
var _indexOfCompareFn = require("./indexOfCompareFn");
var _events = require("events");
var _bi = require("@wix/bex-core/bi");
const asStoredColumnsOrNull = customColumnsResult => Array.isArray(customColumnsResult) ? customColumnsResult : null;
class CustomColumnsState {
  constructor(params) {
    (0, _defineProperty2.default)(this, "table", void 0);
    (0, _defineProperty2.default)(this, "container", void 0);
    (0, _defineProperty2.default)(this, "columnsCollection", void 0);
    (0, _defineProperty2.default)(this, "dragAndDrop", void 0);
    (0, _defineProperty2.default)(this, "customColumnsHistory", void 0);
    (0, _defineProperty2.default)(this, "onColumnClick", void 0);
    (0, _defineProperty2.default)(this, "_didFirstColumnsMerge", void 0);
    (0, _defineProperty2.default)(this, "_performedCustomColumnsActions", new Map());
    (0, _defineProperty2.default)(this, "initTask", new _bexCore.TaskState());
    (0, _defineProperty2.default)(this, "_touched", false);
    (0, _defineProperty2.default)(this, "searchValue", '');
    (0, _defineProperty2.default)(this, "select", new _bexCore.SelectState({
      keyGetter: column => column.id
    }));
    (0, _defineProperty2.default)(this, "events", new _events.EventEmitter());
    (0, _defineProperty2.default)(this, "onColumnCheckboxToggle", (0, _mobx.action)(column => {
      const {
        select,
        onColumnClick
      } = this;
      select.toggle(column);
      onColumnClick == null || onColumnClick(column, select.isChecked(column.id));
    }));
    (0, _defineProperty2.default)(this, "setSearchValue", (0, _mobx.action)(value => {
      this.searchValue = value;
      this.columnsCollection.refreshAllPages();
    }));
    this.table = params.table;
    this.container = params.container;
    this.columnsCollection = new _bexCore.CollectionState({
      ...this.container,
      events: {},
      queryName: [this.container.environment.componentId, this.table.collection.queryName, 'customColumns'].filter(Boolean).join('/'),
      fetchData: async () => {
        const {
          filteredColumns
        } = this;
        const items = filteredColumns.filter(column => column.hiddenFromCustomColumnsSelection !== true);
        return {
          items
        };
      },
      filters: {},
      itemKey: item => item.id,
      itemName: item => item.name
    });
    if (params.dragAndDrop) {
      const {
        CustomColumnsDragAndDropState
      } = params.dragAndDrop;
      this.dragAndDrop = new CustomColumnsDragAndDropState({
        customColumns: this,
        components: params.dragAndDrop,
        modalsContainerRef: params.modalsContainerRef
      });
    }
    this.customColumnsHistory = this.table.collection.persistQueryToUrl ? new _CustomColumnsHistoryState.CustomColumnsHistoryState({
      customColumns: this,
      history: params.container.history
    }) : null;
    (0, _mobx.makeObservable)(this, {
      searchValue: _mobx.observable,
      persistCustomColumns: _mobx.action.bound,
      setSearchValue: _mobx.action.bound,
      toSelectedColumns: _mobx.computed,
      orderedColumns: _mobx.computed,
      selectedOrderedColumns: _mobx.computed,
      filteredColumns: _mobx.computed,
      init: _mobx.action
    });
  }
  get orderedColumns() {
    const {
      dragAndDrop,
      table
    } = this;
    const {
      columns,
      customColumnsState
    } = table;
    if (customColumnsState != null && customColumnsState.dragAndDrop && dragAndDrop) {
      return dragAndDrop.orderedColumns;
    }
    return columns;
  }
  get selectedOrderedColumns() {
    const {
      orderedColumns,
      table: {
        selectedColumns: {
          value: selectedColumns
        }
      }
    } = this;
    return orderedColumns.filter(column => selectedColumns.some(selectedColumn => selectedColumn.id === column.id && selectedColumn.isSelected));
  }
  async persistCustomColumns() {
    const {
      table
    } = this;
    const {
      dataCapsule,
      viewsProps
    } = table;

    // if views enabled columns persists inside the view instead of data capsule
    if (viewsProps) {
      return;
    }
    this._touched = true;
    await dataCapsule.setItem('custom-columns', table.selectedColumns.value);
  }
  registerSelectedColumnChange() {
    const {
      table
    } = this;
    table.selectedColumns.events.on('refresh', this.persistCustomColumns);
    return () => {
      table.selectedColumns.events.off('refresh', this.persistCustomColumns);
    };
  }
  mergeNewColumns() {
    const {
      table: {
        columns,
        selectedColumns,
        _toStoredColumn,
        customColumnsState
      },
      _didFirstColumnsMerge
    } = this;
    const defaultHidden = !_didFirstColumnsMerge && !!selectedColumns.value.length;
    const mergeTargetSelectedColumns = [...selectedColumns.value];
    if ((customColumnsState == null ? void 0 : customColumnsState.dragAndDrop) == null) {
      return [...mergeTargetSelectedColumns.filter(s => columns.every(c => s.id !== c.id)), ...columns.map(c => {
        const existing = selectedColumns.value.find(s => s.id === c.id);
        if (existing == null) {
          return _toStoredColumn(c);
        }
        return {
          ...existing,
          isSelected: c.hideable === false || c.hiddenFromCustomColumnsSelection || existing.isSelected
        };
      })];
    }
    const diffColumns = columns.filter(c => selectedColumns.value.every(s => s.id !== c.id)).map(c => _toStoredColumn({
      ...c,
      defaultHidden: defaultHidden || c.defaultHidden
    }));

    // place new columns according to their order in the original columns prop
    diffColumns.forEach(d => {
      const originalIndex = columns.findIndex(c => c.id === d.id);
      const afterId = originalIndex > 0 ? columns[originalIndex - 1].id : null;
      const afterIndex = afterId != null ? mergeTargetSelectedColumns.findIndex(c => c.id === afterId) + 1 : originalIndex === 0 ? 0 : mergeTargetSelectedColumns.length;
      mergeTargetSelectedColumns.splice(afterIndex, 0, d);
    });
    this._didFirstColumnsMerge = true;
    return mergeTargetSelectedColumns;
  }
  getStickyColumnsCount({
    stickyColumns
  }) {
    const {
      dragAndDrop,
      table: {
        selectedColumns: {
          value: selectedColumns
        }
      }
    } = this;
    if (dragAndDrop == null) {
      return stickyColumns;
    }
    const {
      reorderDisabled: reorderDisabledColumns
    } = dragAndDrop.orderedColumnsByReorderDisabled;
    if (!reorderDisabledColumns.length) {
      return stickyColumns;
    }
    return dragAndDrop.orderedColumnsByReorderDisabled.reorderDisabled.filter(column => selectedColumns.some(selectedColumn => selectedColumn.id === column.id && selectedColumn.isSelected)).length;
  }
  get toSelectedColumns() {
    const {
      select,
      table: {
        selectedColumns: {
          value
        }
      }
    } = this;
    return value.map(({
      id
    }) => ({
      id,
      isSelected: select.isChecked(id)
    }));
  }
  get selectionChanged() {
    const {
      toSelectedColumns,
      table: {
        selectedColumns: {
          value
        }
      }
    } = this;
    if (value.length !== toSelectedColumns.length) {
      return true;
    }
    for (let i = 0; i < value.length; i++) {
      const a = value[i];
      const b = toSelectedColumns[i];
      if (a.id !== b.id || a.isSelected !== b.isSelected) {
        return true;
      }
    }
    return false;
  }
  init() {
    var _this$dragAndDrop, _this$customColumnsHi;
    const {
      table
    } = this;
    table.customColumnsStateInitialized = true;
    const disposers = [(0, _mobx.reaction)(() => this.table.selectedColumns.value, async selectedColumns => {
      const {
        select,
        columnsCollection
      } = this;
      select.clear();
      select.forceSetMany(selectedColumns.map(({
        id,
        isSelected
      }) => ({
        value: {
          id
        },
        status: isSelected ? select.finalStatus : select.startStatus
      })));
      await columnsCollection.refreshAllPages();
    }, {
      fireImmediately: true
    }), (0, _mobx.reaction)(() => this.select.selectedValues, () => {
      const {
        table: {
          selectedColumns
        }
      } = this;
      if (!this.selectionChanged) {
        return;
      }
      selectedColumns.setValue(this.toSelectedColumns, {
        emitEvents: ['change', 'beforeRefresh', 'refresh']
      });
    }), this.registerSelectedColumnChange(), this.columnsCollection.init(), (_this$dragAndDrop = this.dragAndDrop) == null ? void 0 : _this$dragAndDrop.init(), (_this$customColumnsHi = this.customColumnsHistory) == null ? void 0 : _this$customColumnsHi.init()];
    return () => {
      disposers.forEach(disposer => disposer == null ? void 0 : disposer());
    };
  }
  async _getStoredCustomColumns() {
    const {
      dataCapsule
    } = this.table;
    try {
      const storedValue = await asStoredColumnsOrNull(await dataCapsule.getItem('custom-columns'));
      this._touched = storedValue != null;
      return storedValue;
    } catch (e) {
      if (e instanceof Error && e.message === 'Key was not found in capsule') {
        return null;
      }
      throw e;
    }
  }
  _tableInit() {
    const {
      initTask,
      table: {
        multi: {
          collections
        }
      }
    } = this;
    initTask.runOnce(async () => {
      try {
        const beforeInitialFetchListeners = this.events.listeners('beforeInitialFetch');
        await Promise.all(beforeInitialFetchListeners.map(l => l()));
        await this._fetchFromStorage();
      } catch (e) {
        console.error(e);
      }
    });
    collections.forEach(collection => {
      if (collection.query.refreshOnColumnsChange) {
        collection.hooks.addListener('beforeInitialFetch', () => initTask.status.promise);
      }
    });
  }
  async _fetchFromStorage() {
    var _customColumnsState$c;
    const {
      table: {
        viewsProps,
        columns,
        selectedColumns,
        customColumnsState,
        _toStoredColumn
      }
    } = this;
    if (viewsProps) {
      return;
    }
    if (customColumnsState != null && (_customColumnsState$c = customColumnsState.customColumnsHistory) != null && _customColumnsState$c._selectedColumnsFromUrl) {
      return;
    }
    const storedCustomColumns = await this._getStoredCustomColumns();
    if (storedCustomColumns == null) {
      return;
    }
    const selectedColumnsFromStorage = columns.map(tableColumn => {
      const existing = storedCustomColumns.find(c => (c == null ? void 0 : c.id) === tableColumn.id);

      // If the column is not found in the stored columns, it means it was added after the last visit, so its "isSelected" state should be calculated based on the column prop passed via code
      if (existing == null) {
        return _toStoredColumn(tableColumn);
      }

      // If the column is found in the stored columns, it means it was already configured by the user, so its  "isSelected" state should be taken from the stored columns
      const {
        id,
        name,
        hideable,
        hiddenFromCustomColumnsSelection
      } = tableColumn;
      return {
        id,
        name,
        isSelected: storedCustomColumns.some(c => (c == null ? void 0 : c.id) === id && (c == null ? void 0 : c.isSelected) !== false) || !hideable || hiddenFromCustomColumnsSelection === true
      };
    });
    selectedColumns.setValue(customColumnsState != null && customColumnsState.dragAndDrop ? selectedColumnsFromStorage.sort((0, _indexOfCompareFn.indexOfCompareFn)(storedCustomColumns, e => e == null ? void 0 : e.id)) : selectedColumnsFromStorage);
  }
  customizeColumnsInSidePanelBi({
    actionName
  }) {
    if (this._performedCustomColumnsActions.get(actionName)) {
      return;
    }
    this._performedCustomColumnsActions.set(actionName, true);
    this.table.reportBi((0, _bexCore.withoutDefaults)(_bi.cairoCustomizeColumnsInSidePanel)({
      actionName
    }));
  }
  get filteredColumns() {
    const {
      orderedColumns,
      searchValue
    } = this;
    if (!searchValue.trim()) {
      return orderedColumns;
    }
    const searchLower = searchValue.toLowerCase();
    return orderedColumns.filter(column => {
      const name = column.name || (typeof column.title === 'string' ? column.title : column.id);
      return name.toLowerCase().includes(searchLower);
    });
  }
}
exports.CustomColumnsState = CustomColumnsState;
//# sourceMappingURL=CustomColumnsState.js.map