text: import unionWith from 'lodash/unionWith';
  import { storableError } from '../../util/errors';
  import { addMarketplaceEntities } from '../../ducks/marketplaceData.duck';
  import { convertUnitToSubUnit, unitDivisor } from '../../util/currency';
  import config from '../../config';
  
  // ================ Action types ================ //
  
  export const SEARCH_LISTINGS_REQUEST = 'app/SearchPage/SEARCH_LISTINGS_REQUEST';
  export const SEARCH_LISTINGS_SUCCESS = 'app/SearchPage/SEARCH_LISTINGS_SUCCESS';
  export const SEARCH_LISTINGS_ERROR = 'app/SearchPage/SEARCH_LISTINGS_ERROR';
  
  export const SEARCH_MAP_LISTINGS_REQUEST = 'app/SearchPage/SEARCH_MAP_LISTINGS_REQUEST';
  export const SEARCH_MAP_LISTINGS_SUCCESS = 'app/SearchPage/SEARCH_MAP_LISTINGS_SUCCESS';
  export const SEARCH_MAP_LISTINGS_ERROR = 'app/SearchPage/SEARCH_MAP_LISTINGS_ERROR';
  
  export const SEARCH_MAP_SET_ACTIVE_LISTING = 'app/SearchPage/SEARCH_MAP_SET_ACTIVE_LISTING';
  
  // ================ Reducer ================ //
  
  const initialState = {
    pagination: null,
    searchParams: null,
    searchInProgress: false,
    searchListingsError: null,
    currentPageResultIds: [],
    searchMapListingIds: [],
    searchMapListingsError: null,
  };
  
  const resultIds = data => data.data.map(l => l.id);
  
  const listingPageReducer = (state = initialState, action = {}) => {
    const { type, payload } = action;
    switch (type) {
      case SEARCH_LISTINGS_REQUEST:
        return {
          ...state,
          searchParams: payload.searchParams,
          searchInProgress: true,
          searchMapListingIds: [],
          searchListingsError: null,
        };
      case SEARCH_LISTINGS_SUCCESS:
        return {
          ...state,
          currentPageResultIds: resultIds(payload.data),
          pagination: payload.data.meta,
          searchInProgress: false,
        };
      case SEARCH_LISTINGS_ERROR:
        // eslint-disable-next-line no-console
        console.error(payload);
        return { ...state, searchInProgress: false, searchListingsError: payload };
  
      case SEARCH_MAP_LISTINGS_REQUEST:
        return {
          ...state,
          searchMapListingsError: null,
        };
      case SEARCH_MAP_LISTINGS_SUCCESS: {
        const searchMapListingIds = unionWith(
          state.searchMapListingIds,
          resultIds(payload.data),
          (id1, id2) => id1.uuid === id2.uuid
        );
        return {
          ...state,
          searchMapListingIds,
        };
      }
      case SEARCH_MAP_LISTINGS_ERROR:
        // eslint-disable-next-line no-console
        console.error(payload);
        return { ...state, searchMapListingsError: payload };
  
      case SEARCH_MAP_SET_ACTIVE_LISTING:
        return {
          ...state,
          activeListingId: payload,
        };
      default:
        return state;
    }
  };
  
  export default listingPageReducer;
  
  // ================ Action creators ================ //
  
  export const searchListingsRequest = searchParams => ({
    type: SEARCH_LISTINGS_REQUEST,
    payload: { searchParams },
  });
  
  export const searchListingsSuccess = response => ({
    type: SEARCH_LISTINGS_SUCCESS,
    payload: { data: response.data },
  });
  
  export const searchListingsError = e => ({
    type: SEARCH_LISTINGS_ERROR,
    error: true,
    payload: e,
  });
  
  export const searchMapListingsRequest = () => ({ type: SEARCH_MAP_LISTINGS_REQUEST });
  
  export const searchMapListingsSuccess = response => ({
    type: SEARCH_MAP_LISTINGS_SUCCESS,
    payload: { data: response.data },
  });
  
  export const searchMapListingsError = e => ({
    type: SEARCH_MAP_LISTINGS_ERROR,
    error: true,
    payload: e,
  });
  
  export const searchListings = searchParams => (dispatch, getState, sdk) => {
    dispatch(searchListingsRequest(searchParams));
  
    const priceSearchParams = priceParam => {
      const inSubunits = value =>
        convertUnitToSubUnit(value, unitDivisor(config.currencyConfig.currency));
      const values = priceParam ? priceParam.split(',') : [];
      return priceParam && values.length === 2
        ? {
            price: [inSubunits(values[0]), inSubunits(values[1]) + 1].join(','),
          }
        : {};
    };
  
    const { perPage, price, ...rest } = searchParams;
    const priceMaybe = priceSearchParams(price);
    const params = {
      ...rest,
      ...priceMaybe,
      per_page: perPage,
    };
  
    return sdk.listings
      .query(params)
      .then(response => {
        dispatch(addMarketplaceEntities(response));
        dispatch(searchListingsSuccess(response));
        return response;
      })
      .catch(e => {
        dispatch(searchListingsError(storableError(e)));
        throw e;
      });
  };
  
  export const setActiveListing = listingId => ({
    type: SEARCH_MAP_SET_ACTIVE_LISTING,
    payload: listingId,
  });
  
  export const searchMapListings = searchParams => (dispatch, getState, sdk) => {
    dispatch(searchMapListingsRequest(searchParams));
  
    const { perPage, ...rest } = searchParams;
    const params = {
      ...rest,
      per_page: perPage,
    };
  
    return sdk.listings
      .query(params)
      .then(response => {
        dispatch(addMarketplaceEntities(response));
        dispatch(searchMapListingsSuccess(response));
        return response;
      })
      .catch(e => {
        dispatch(searchMapListingsError(storableError(e)));
        throw e;
      });
  };
  