
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.fetchTagsIfNeeded = fetchTagsIfNeeded;
exports.fetchCategoriesIfNeeded = fetchCategoriesIfNeeded;

var _humps = require('humps');

var _index = require('../utils/index');

var _normalizr = require('normalizr');

var _index2 = require('../schemas/index');

var _index3 = require('../constants/index');

var CONSTANTS = _interopRequireWildcard(_index3);

var _isomorphicFetch = require('isomorphic-fetch');

var _isomorphicFetch2 = _interopRequireDefault(_isomorphicFetch);

var _qs = require('qs');

var _qs2 = _interopRequireDefault(_qs);

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

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var groupEnum = CONSTANTS.groupEnum;
var pathEnum = CONSTANTS.apiPathEnum;

function requestGroups(groupType, groupNames) {
  var type = groupType === groupEnum.CATEGORY ? CONSTANTS.FETCH_CATEGORIES_REQUEST : CONSTANTS.FETCH_TAGS_REQUEST;
  return {
    type: type,
    groups: groupNames
  };
}

function failToReceiveGroups(groupType, groupNames, error) {
  var type = groupType === groupEnum.CATEGORY ? CONSTANTS.FETCH_CATEGORIES_FAILURE : CONSTANTS.FETCH_TAGS_FAILURE;
  return {
    type: type,
    groups: groupNames,
    error: error,
    failedAt: Date.now()
  };
}

function receiveGroups(groupType, response) {
  var type = groupType === groupEnum.CATEGORY ? CONSTANTS.FETCH_CATEGORIES_SUCCESS : CONSTANTS.FETCH_TAGS_SUCCESS;
  return {
    type: type,
    response: response,
    receivedAt: Date.now()
  };
}

function fetchGroups(groupType, groupNames) {
  return function (dispatch) {
    dispatch(requestGroups(groupType, groupNames));

    var query = _qs2.default.stringify({ where: JSON.stringify({ name: { '$in': groupNames } }) });
    var path = void 0;
    var schema = void 0;

    if (groupType === groupEnum.CATEGORY) {
      path = pathEnum.CATEGORY;
      schema = _index2.category;
    } else if (groupType === groupEnum.TAG) {
      path = pathEnum.TAG;
      schema = _index2.tag;
    } else {
      return dispatch(failToReceiveGroups(groupType, groupNames, new Error('group type should be one of category or tag')));
    }

    return (0, _isomorphicFetch2.default)((0, _index.formatUrl)(path + '?' + query)).then(function (response) {
      if (response.status >= 400) {
        throw new Error('Bad response from API, response:' + JSON.stringify(response));
      }
      return response.json();
    }).then(function (response) {
      var camelizedJson = (0, _humps.camelizeKeys)(response);
      dispatch(receiveGroups(groupType, (0, _normalizr.normalize)(camelizedJson.items, (0, _normalizr.arrayOf)(schema))));
    }, function (error) {
      dispatch(failToReceiveGroups(groupType, groupNames, error));
    });
  };
}

function dedupGroups() {
  var state = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
  var groupType = arguments[1];
  var groupNames = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];

  groupNames = Array.isArray(groupNames) ? groupNames : [groupNames];
  var existedGroups = (groupType === groupEnum.CATEGORY ? state.categories : state.tags) || {};
  var rtn = [];
  groupNames.forEach(function (groupName) {
    if (!existedGroups.hasOwnProperty(groupName) || existedGroups[groupName].error) {
      rtn.push(groupName);
    }
  });
  return rtn;
}

function fetchTagsIfNeeded(tags) {
  return function (dispatch, getState) {
    var deduppedTags = dedupGroups(getState(), groupEnum.TAG, tags);

    if (deduppedTags.length !== 0) {
      return dispatch(fetchGroups(groupEnum.TAG, deduppedTags));
    }
    return Promise.resolve();
  };
}

function fetchCategoriesIfNeeded(categories) {
  return function (dispatch, getState) {
    var deduppedCategories = dedupGroups(getState(), groupEnum.CATEGORY, categories);

    if (deduppedCategories.length !== 0) {
      return dispatch(fetchGroups(groupEnum.CATEGORY, deduppedCategories));
    }
    return Promise.resolve();
  };
}