"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.QueryHistoryState = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _mobx = require("mobx");
var _services = require("../services");
function parseSortString(sortFromUrl) {
  return sortFromUrl.split(',').map(sortExpression => {
    const [field = '', direction = ''] = sortExpression.split(' ');
    return {
      field: decodeURIComponent(field),
      direction: direction === 'desc' ? 'desc' : 'asc'
    };
  });
}
class QueryHistoryState {
  constructor(params) {
    (0, _defineProperty2.default)(this, "query", void 0);
    (0, _defineProperty2.default)(this, "history", void 0);
    (0, _defineProperty2.default)(this, "sortSearchParamName", 'sort');
    this.query = params.query;
    this.history = params.history;
    (0, _mobx.makeObservable)(this, {
      init: _mobx.action,
      persistAll: _mobx.action,
      _preInitHistoryPersistence: _mobx.action
    });
    this._preInitHistoryPersistence();
  }
  _preInitHistoryPersistence() {
    const {
      query,
      history
    } = this;
    const searchParams = new URLSearchParams(history.location.search);
    Object.values(query.filtersEntries).forEach(([key, filter]) => {
      const valueFromUrl = searchParams.get(key);
      if (valueFromUrl != null) {
        query._initializedFromHistory = true;
        filter.applyFromQueryString(valueFromUrl);
      }
    });
    const sortFromUrl = searchParams.get(this.sortSearchParamName);
    if (sortFromUrl) {
      query._initializedFromHistory = true;
      query.sort.setSortQuery(parseSortString(sortFromUrl), {
        emitChangeEvent: true
      });
    }
  }
  init() {
    const {
      history,
      query
    } = this;
    const searchParams = new URLSearchParams(history.location.search);
    const disposers = [
    // Apply URL values to dynamically added filters
    (0, _mobx.reaction)(() => query.filtersEntries.map(([key]) => key), () => {
      for (const [key, filter] of query.filtersEntries) {
        const valueFromUrl = searchParams.get(key);
        if (valueFromUrl != null) {
          filter.applyFromQueryString(valueFromUrl);
        }
      }
    }),
    // Persist all filter/sort changes to URL
    (0, _mobx.reaction)(() => query.filtersKeyHash, () => this.persistAll(), {
      delay: 250
    }), (0, _mobx.reaction)(() => query.search.value, () => this.persistAll(), {
      delay: 250
    }), (0, _mobx.reaction)(() => query.sort.value.map(({
      field,
      direction
    }) => ({
      field,
      direction
    })), () => this.persistAll(), {
      delay: 250
    })];
    this.persistAll();
    return () => disposers.forEach(d => d());
  }
  _setFilterValueToSearchParams(searchParams, key, filter) {
    if (!filter.isEmpty) {
      searchParams.set(key, filter.toQueryString);
    } else {
      searchParams.delete(key);
    }
  }
  persistAll() {
    const {
      history,
      sortSearchParamName,
      query: {
        filtersEntries,
        sort
      }
    } = this;
    (0, _services.replaceSearchParamsWith)(history, searchParams => {
      for (const [key, filter] of filtersEntries) {
        this._setFilterValueToSearchParams(searchParams, key, filter);
      }
      if (sort.value.length) {
        searchParams.set(sortSearchParamName, sort.value.map(({
          field,
          direction
        }) => `${encodeURIComponent(field)} ${direction}`).join(','));
      } else {
        searchParams.delete(sortSearchParamName);
      }
    });
  }
}
exports.QueryHistoryState = QueryHistoryState;
//# sourceMappingURL=QueryHistoryState.js.map