/* eslint no-param-reassign: "off" */

import _ from 'lodash';
import { ActionTypes } from 'lore-utils';

/*
 * find Reducer Blueprint
 */

function mergeDataAndIntersectWithDictionaryKeys(oldData, newData, dictionary) {
  const ids = _.map(oldData, 'id');
  const newIds = _.map(newData, 'id');
  const combinedIds = _.union(ids, newIds);
  const dictionaryKeys = _.keys(dictionary);

  // If any ids are Numbers, convert them to Strings so we can compare equality
  // with the dictionary keys
  const combinedIdsAsStrings = combinedIds.map(function(id) {
    return id.toString();
  });

  const idsInDictionary = _.intersection(combinedIdsAsStrings, dictionaryKeys);
  return idsInDictionary.map(function(id) {
    return dictionary[id];
  });
}

export default function(modelName) {
  const initialState = {};
  // const EMPTY_QUERY_KEY = JSON.stringify({});

  return function find(state, action, options) {
    state = state || initialState;
    let nextState = _.assign({}, state);
    const byId = options.nextState.byId;
    const byCid = options.nextState.byCid;

    switch (action.type) {
      case ActionTypes.fetchPlural(modelName): {
        const query = JSON.stringify(action.query);
        nextState[query] = nextState[query] || {};
        nextState[query] = _.assign({}, action.payload, {
          data: mergeDataAndIntersectWithDictionaryKeys(
            nextState[query].data,
            action.payload.data,
            byId
          )
        });
        return nextState;
      }

      case ActionTypes.update(modelName): {
        nextState = _.mapValues(nextState, function(collection, key) {
          collection.data = collection.data.map(function(datum) {
            if (datum.id === action.payload.id) {
              return action.payload;
            }
            return datum;
          });

          return collection;
        });
        return nextState;
      }

      case ActionTypes.remove(modelName): {
        nextState = _.mapValues(nextState, function(collection, key) {
          collection.data = collection.data.map(function(datum) {
            if (datum.id === action.payload.id) {
              return action.payload;
            }
            return datum;
          });

          return collection;
        });
        return nextState;
      }

      default:
        return nextState;
    }
  };
}

@@ -1498,32 +1498,426 @@
 State;%0A      %7D%0A%0A
+      case ActionTypes.refetchPlural(modelName): %7B%0A        const query = JSON.stringify(action.query);%0A        nextState%5Bquery%5D = nextState%5Bquery%5D %7C%7C %7B%7D;%0A        nextState%5Bquery%5D = _.assign(%7B%7D, action.payload, %7B%0A          data: mergeDataAndIntersectWithDictionaryKeys(%0A            %5B%5D,%0A            action.payload.data,%0A            byId%0A          )%0A        %7D);%0A        return nextState;%0A      %7D%0A%0A
       case Actio

add refetch ability to reset a specific find query