'use strict';

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

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

exports.default = updateState;

var _parseJSON = require('../utils/parseJSON');

var _parseJSON2 = _interopRequireDefault(_parseJSON);

var _commitExcessActions = require('./commitExcessActions');

var _commitExcessActions2 = _interopRequireDefault(_commitExcessActions);

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

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function recompute(previousLiftedState, storeState, action) {
  var nextActionId = arguments.length <= 3 || arguments[3] === undefined ? 1 : arguments[3];
  var isExcess = arguments[4];

  var actionId = nextActionId - 1;
  var liftedState = _extends({}, previousLiftedState);
  liftedState.stagedActionIds = [].concat(_toConsumableArray(liftedState.stagedActionIds), [actionId]);
  liftedState.actionsById = _extends({}, liftedState.actionsById);
  if (action.type === 'PERFORM_ACTION') {
    liftedState.actionsById[actionId] = action;
  } else {
    liftedState.actionsById[actionId] = {
      action: action.action || action,
      timestamp: action.timestamp || Date.now(),
      type: 'PERFORM_ACTION'
    };
  }
  liftedState.nextActionId = nextActionId;
  liftedState.computedStates = [].concat(_toConsumableArray(liftedState.computedStates), [{ state: storeState }]);
  liftedState.currentStateIndex++;

  if (isExcess) (0, _commitExcessActions2.default)(liftedState);

  return liftedState;
}

function updateState(store, request, onInstancesChanged, instance, sync) {
  if (request.type === 'START' && onInstancesChanged) onInstancesChanged(request.id, request.name);

  var payload = (0, _parseJSON2.default)(request.payload);
  if (typeof payload === 'undefined') return null;

  var newState = void 0;
  var action = {};
  if (request.action) action = (0, _parseJSON2.default)(request.action) || {};

  if (!instance) store.liftedStore.setInstance(request.id);

  switch (request.type) {
    case 'INIT':
      newState = recompute(store.liftedStore.getInitialState(), payload, { action: { type: '@@INIT' }, timestamp: action.timestamp || Date.now() });
      break;
    case 'ACTION':
      var liftedState = store.liftedStore.getState(request.id);
      newState = recompute(liftedState, payload, action, request.nextActionId || liftedState.nextActionId + 1, request.isExcess);
      break;
    case 'STATE':
      newState = payload;
      break;
    default:
      return null;
  }

  store.liftedStore.setState(newState, request.id, function () {
    store.init(request);
    if (onInstancesChanged) onInstancesChanged(request.id, request.name);
  });

  if (sync && request.id === instance) sync(newState, instance);

  return newState;
}
module.exports = exports['default'];