import { createConnector } from "react-instantsearch-dom";
import { refineValue } from "react-instantsearch-core/dist/es/core/indexUtils";

/* 
* Custom connectRefinementsApplied() will return the props:
* - refinements (all current refinements and sort)
* - refine (function to update the searchState on click events)
*/
const connectRefinementsApplied = createConnector({
  displayName: "ConnectedRefinementsApplied",
  getProvidedProps: (props, searchState, searchResults, metadata) => {
    const { sortBy: sortValue,  } = searchState || {};
    const { contextValue, indexContextValue, sortList } = props || {};
    // refinementList is taken from the Algolia connectCurrentRefinements function
    // https://github.com/algolia/instantsearch/blob/master/packages/react-instantsearch-core/src/connectors/connectCurrentRefinements.js#L25
    const refinementList = metadata.reduce((res, meta) => {
      if (typeof meta.items !== "undefined") {
        if (meta.id === "query") {
          return res;
        } else {
          return res.concat(
            meta.items.map((item) => ({
              ...item,
              id: meta.id,
              index: meta.index,
            }))
          );
        }
      }
      return res;
    }, []);

    // check if the sort has been reset to the default index so we don't display it in the applied filters
    const hasSortValue = sortList.some(({value: replicaName}) => replicaName === sortValue);
    // custom sortBy object, structure is similar to the filter facet items
    const sortBy = hasSortValue ? [{
      id: "sortBy",
      items: [{label: sortValue}],
      // emulating the clear value function built by Algolia
      value: (state) => {
        // we want to clear the sort by resetting to the default index
        const nextValue = { sortBy: contextValue.mainTargetedIndex };
        const resetPage = true;
        // pass in the searchState and use the refineValue function built by Algolia
        // https://github.com/algolia/instantsearch/blob/f802fd0f56d7e898c85e947fa6a3e5c11ff1b6ec/packages/react-instantsearch-core/src/core/indexUtils.js#L104
        return refineValue(
          state,
          nextValue,
          { ais: contextValue, multiIndexContext: indexContextValue },
          resetPage
        );
      }
    }] : [];
    // merge refinementList and sortBy arrays
    const refinements = [].concat(...refinementList).concat(...sortBy);
    return { refinements }
  },
  refine(props, searchState, nextRefinement) {
    // `value` corresponds to our internal clear function computed in each connector metadata.
    const refinementsToClear =
    nextRefinement instanceof Array ? nextRefinement.map((item) => item.value) : [nextRefinement];
    const newSearchState = refinementsToClear.reduce((res, clear) => {
      // we pass the searchState into the clear value function to clear the refinements and sort applied
      return clear(res);
    }, searchState);
    return newSearchState;
  },
});

export default connectRefinementsApplied;