"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.deselectResultItem = exports.setAllResultItemsSelected = exports.setResultItemSelected = exports.searchCsid = exports.search = exports.clearSearchResults = exports.clearSelected = void 0;

var _get = _interopRequireDefault(require("lodash/get"));

var _reducers = require("../reducers");

var _cspace = _interopRequireDefault(require("./cspace"));

var _searchHelpers = require("../helpers/searchHelpers");

var _errorCodes = require("../constants/errorCodes");

var _actionCodes = require("../constants/actionCodes");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const toJS = obj => obj && typeof obj === 'object' && obj.toJS ? obj.toJS() : obj;

const getSortParam = (config, searchDescriptor, columnSetName) => {
  const sortSpec = searchDescriptor.getIn(['searchQuery', 'sort']);
  const [sortColumnName, sortDir] = sortSpec.split(' ');

  if (sortDir && sortDir !== 'desc') {
    return null;
  }

  const column = (0, _get.default)(config, ['recordTypes', searchDescriptor.get('recordType'), 'columns', columnSetName, sortColumnName]);

  if (column && column.sortBy) {
    return column.sortBy + (sortDir ? ' DESC' : '');
  }

  return null;
};

const clearSelected = searchName => ({
  type: _actionCodes.CLEAR_SELECTED,
  meta: {
    searchName
  }
});

exports.clearSelected = clearSelected;

const clearSearchResults = searchName => ({
  type: _actionCodes.CLEAR_SEARCH_RESULTS,
  meta: {
    searchName
  }
});

exports.clearSearchResults = clearSearchResults;

const search = function search(config, searchName, searchDescriptor) {
  let listType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'common';
  let columnSetName = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 'default';
  return (dispatch, getState) => {
    const recordType = searchDescriptor.get('recordType');
    const vocabulary = searchDescriptor.get('vocabulary');
    const csid = searchDescriptor.get('csid');
    const subresource = searchDescriptor.get('subresource');
    const searchQuery = searchDescriptor.get('searchQuery');

    if ((0, _reducers.isSearchPending)(getState(), searchName, searchDescriptor) || (0, _reducers.getSearchResult)(getState(), searchName, searchDescriptor) && !(0, _reducers.isSearchDirty)(getState(), searchName)) {
      // There's already a result for this search. Just set this search to be the most recent.
      dispatch({
        type: _actionCodes.SET_MOST_RECENT_SEARCH,
        meta: {
          searchName,
          searchDescriptor
        }
      });
      return Promise.resolve();
    }

    const listTypeConfig = config.listTypes[listType];
    dispatch({
      type: _actionCodes.SEARCH_STARTED,
      meta: {
        listTypeConfig,
        searchName,
        searchDescriptor
      }
    });
    const recordTypeConfig = config.recordTypes[recordType];

    if (!recordTypeConfig) {
      dispatch({
        type: _actionCodes.SEARCH_REJECTED,
        payload: {
          code: _errorCodes.ERR_UNKNOWN_RECORD_TYPE
        },
        meta: {
          searchName,
          searchDescriptor
        }
      });
      return Promise.reject();
    }

    const recordTypeServicePath = (0, _get.default)(recordTypeConfig, ['serviceConfig', 'servicePath']);

    if (!recordTypeServicePath) {
      dispatch({
        type: _actionCodes.SEARCH_REJECTED,
        payload: {
          code: _errorCodes.ERR_UNKNOWN_RECORD_TYPE
        },
        meta: {
          searchName,
          searchDescriptor
        }
      });
      return Promise.reject();
    }

    const vocabularyServicePath = vocabulary ? (0, _get.default)(recordTypeConfig, ['vocabularies', vocabulary, 'serviceConfig', 'servicePath']) : null;

    if (vocabulary && !vocabularyServicePath) {
      dispatch({
        type: _actionCodes.SEARCH_REJECTED,
        payload: {
          code: _errorCodes.ERR_UNKNOWN_VOCABULARY
        },
        meta: {
          searchName,
          searchDescriptor
        }
      });
      return Promise.reject();
    } // Check for conditions where we just want to create an empty result.
    // These happen when a new record is being created.


    if ( // A related record search for an empty csid.
    searchQuery.get('rel') === '' || // A subresource query without a csid.
    typeof subresource !== 'undefined' && !searchDescriptor.get('csid')) {
      dispatch({
        type: _actionCodes.CREATE_EMPTY_SEARCH_RESULT,
        meta: {
          listTypeConfig,
          searchName,
          searchDescriptor
        }
      });
      return Promise.resolve();
    }

    const nxql = (0, _searchHelpers.advancedSearchConditionToNXQL)(recordTypeConfig.fields, searchQuery.get('as'));
    const requestConfig = {
      params: {
        as: nxql ? "(".concat(nxql, ")") : undefined,
        csid: searchQuery.get('csid'),
        doctype: searchQuery.get('doctype'),
        kw: searchQuery.get('kw'),
        mkRtSbj: searchQuery.get('mkRtSbj'),
        mode: toJS(searchQuery.get('mode')),
        pgNum: searchQuery.get('p'),
        pgSz: searchQuery.get('size'),
        rtSbj: searchQuery.get('rel'),
        rtPredicate: searchQuery.get('relType'),
        sn: searchQuery.get('sn'),
        // accounts screen name
        dn: searchQuery.get('dn'),
        // role display name
        wf_deleted: false
      }
    };

    if (searchQuery.get('sort')) {
      const sortParam = getSortParam(config, searchDescriptor, columnSetName);

      if (!sortParam) {
        dispatch({
          type: _actionCodes.SEARCH_REJECTED,
          payload: {
            code: _errorCodes.ERR_INVALID_SORT
          },
          meta: {
            searchName,
            searchDescriptor
          }
        });
        return Promise.reject();
      }

      requestConfig.params.sortBy = sortParam;
    }

    const pathParts = [recordTypeServicePath];

    if (vocabularyServicePath) {
      pathParts.push(vocabularyServicePath);
      pathParts.push('items');
    }

    if (csid) {
      pathParts.push(csid);
    }

    if (subresource) {
      const subresourceConfig = config.subresources[subresource];
      const subresourceServicePath = subresourceConfig.serviceConfig.servicePath;
      pathParts.push(subresourceServicePath);
    }

    const path = pathParts.join('/');
    return (0, _cspace.default)().read(path, requestConfig) // Insert an artificial delay for testing.
    // .then(response => new Promise((resolve) => {
    //   window.setTimeout(() => {
    //     resolve(response);
    //   }, 1000);
    // }))
    .then(response => dispatch({
      type: _actionCodes.SEARCH_FULFILLED,
      payload: response,
      meta: {
        listTypeConfig,
        searchName,
        searchDescriptor
      }
    })).catch(error => dispatch({
      type: _actionCodes.SEARCH_REJECTED,
      payload: {
        code: _errorCodes.ERR_API,
        error
      },
      meta: {
        searchName,
        searchDescriptor
      }
    }));
  };
};

exports.search = search;

const searchCsid = (config, recordType, csid) => () => {
  const requestConfig = {
    params: {
      as: "(ecm:name = \"".concat(csid, "\")"),
      pgSz: 1,
      wf_deleted: false
    }
  };
  const recordTypeConfig = config.recordTypes[recordType];

  if (!recordTypeConfig) {
    return Promise.reject();
  }

  const recordTypeServicePath = (0, _get.default)(recordTypeConfig, ['serviceConfig', 'servicePath']);

  if (!recordTypeServicePath) {
    return Promise.reject();
  }

  const pathParts = [recordTypeServicePath];
  const serviceType = (0, _get.default)(recordTypeConfig, ['serviceConfig', 'serviceType']);

  if (serviceType === 'authority') {
    const vocabularyServicePath = (0, _get.default)(recordTypeConfig, ['vocabularies', 'all', 'serviceConfig', 'servicePath']);

    if (!vocabularyServicePath) {
      return Promise.reject();
    }

    pathParts.push(vocabularyServicePath);
    pathParts.push('items');
  }

  const path = pathParts.join('/');
  return (0, _cspace.default)().read(path, requestConfig);
};

exports.searchCsid = searchCsid;

const setResultItemSelected = function setResultItemSelected(config, searchName, searchDescriptor) {
  let listType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'common';
  let index = arguments.length > 4 ? arguments[4] : undefined;
  let isSelected = arguments.length > 5 ? arguments[5] : undefined;
  const listTypeConfig = config.listTypes[listType];
  return {
    type: _actionCodes.SET_RESULT_ITEM_SELECTED,
    payload: isSelected,
    meta: {
      listTypeConfig,
      searchName,
      searchDescriptor,
      index
    }
  };
};

exports.setResultItemSelected = setResultItemSelected;

const setAllResultItemsSelected = function setAllResultItemsSelected(config, searchName, searchDescriptor) {
  let listType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'common';
  let isSelected = arguments.length > 4 ? arguments[4] : undefined;
  let filter = arguments.length > 5 ? arguments[5] : undefined;
  const listTypeConfig = config.listTypes[listType];
  return {
    type: _actionCodes.SET_ALL_RESULT_ITEMS_SELECTED,
    payload: isSelected,
    meta: {
      filter,
      listTypeConfig,
      searchName,
      searchDescriptor
    }
  };
};

exports.setAllResultItemsSelected = setAllResultItemsSelected;

const deselectResultItem = (searchName, csid) => ({
  type: _actionCodes.DESELECT_RESULT_ITEM,
  meta: {
    searchName,
    csid
  }
});

exports.deselectResultItem = deselectResultItem;