"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.SPREADSHEET_CUSTOM_COLUMNS_KEY = exports.CustomColumnsState = exports.CUSTOM_COLUMNS_KEY = 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");
var _CustomColumnsPanelStateBase = require("./CustomColumnsPanelStateBase");
// Legacy `custom-columns` stays bound to non-spreadsheet layouts so existing
// stored values keep their meaning; spreadsheet uses a sibling key.
const CUSTOM_COLUMNS_KEY = exports.CUSTOM_COLUMNS_KEY = 'custom-columns';
const SPREADSHEET_CUSTOM_COLUMNS_KEY = exports.SPREADSHEET_CUSTOM_COLUMNS_KEY = 'spreadsheet-custom-columns';
const getCustomColumnsKeyForLayout = layout => layout === 'spreadsheet' ? SPREADSHEET_CUSTOM_COLUMNS_KEY : CUSTOM_COLUMNS_KEY;
const asStoredColumnsOrNull = customColumnsResult => Array.isArray(customColumnsResult) ? customColumnsResult : null;
class CustomColumnsState extends _CustomColumnsPanelStateBase.CustomColumnsPanelStateBase {
  constructor(params) {
    super({
      container: params.container,
      queryName: [params.container.environment.componentId, params.table.collection.queryName, 'customColumns'].filter(Boolean).join('/')
    });
    (0, _defineProperty2.default)(this, "table", void 0);
    (0, _defineProperty2.default)(this, "dragAndDrop", void 0);
    (0, _defineProperty2.default)(this, "customColumnsHistory", 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, "events", new _events.EventEmitter());
    this.table = params.table;
    if (params.dragAndDrop) {
      const {
        CustomColumnsDragAndDropState
      } = params.dragAndDrop;
      this.dragAndDrop = new CustomColumnsDragAndDropState({
        customColumns: this,
        dataSource: {
          get columns() {
            return params.table.columns;
          },
          selectedColumns: params.table.selectedColumns
        },
        components: params.dragAndDrop,
        modalsContainerRef: params.modalsContainerRef
      });
    }
    this.customColumnsHistory = this.table.collection.persistQueryToUrl ? new _CustomColumnsHistoryState.CustomColumnsHistoryState({
      customColumns: this,
      history: params.container.history
    }) : null;
    this.initBaseObservables();
    (0, _mobx.makeObservable)(this, {
      persistCustomColumns: _mobx.action.bound,
      toSelectedColumns: _mobx.computed,
      selectedOrderedColumns: _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() {
    var _table$layoutState;
    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(getCustomColumnsKeyForLayout((_table$layoutState = table.layoutState) == null ? void 0 : _table$layoutState.viewType), 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(), (0, _mobx.reaction)(() => {
      var _this$table$layoutSta;
      return (_this$table$layoutSta = this.table.layoutState) == null ? void 0 : _this$table$layoutSta.viewType;
    }, async (newLayout, prevLayout) => {
      if (!newLayout || !prevLayout || newLayout === prevLayout) {
        return;
      }
      if (this.table._cacheRestoredLayout === newLayout) {
        return;
      }
      // Views path is handled by CollectionViewsState's own reaction.
      if (this.table.viewsProps) {
        return;
      }
      const stored = await this._getStoredCustomColumns();
      if (stored == null) {
        this.table.selectedColumns.reset();
      } else {
        await this._fetchFromStorage();
      }
    })];
    return () => {
      disposers.forEach(disposer => disposer == null ? void 0 : disposer());
    };
  }
  async _getStoredCustomColumns() {
    const {
      dataCapsule
    } = this.table;
    try {
      var _this$table$layoutSta2;
      const storedValue = await asStoredColumnsOrNull(await dataCapsule.getItem(getCustomColumnsKeyForLayout((_this$table$layoutSta2 = this.table.layoutState) == null ? void 0 : _this$table$layoutSta2.viewType)));
      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.hasUrlColumnsForCurrentLayout) {
      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 showFieldTypeIcons() {
    return this.table.showFieldTypeIcons;
  }
  get collectionDataExtension() {
    return this.table.collectionDataExtension;
  }
  get sidePanelTransition() {
    return this.table.sidePanel.transition;
  }
  onClose() {
    this.table.reportBi((0, _bexCore.withoutDefaults)(_bi.cairoFiltersPanelUsed)({
      isOpened: false,
      feature: 'Custom Columns',
      origin: 'X Button'
    }));
    this.table.sidePanel.close();
  }
}
exports.CustomColumnsState = CustomColumnsState;
//# sourceMappingURL=CustomColumnsState.js.map