import { Map } from 'immutable'

/**
 * The start action for the update reducer
 * @param  {Immutable.Map} state - current reducer state
 * @param  {Object} action - action object
 *
 * @return {Immutable.Map} - updated state
 */
export const start = (state, action) => {

  const uid = action.record.get(action.uidField)

  // Create updated record tuple
  // We have to create a tuple here in order to preserve the Integer typed keys

  const previousRecord = state.getIn(['raw', uid])
  const updatedRecordTuple = Map([[uid, previousRecord.merge(action.record)]])

  // Create tuple for previous version of the item
  const previousRecordTuple = Map([[uid, previousRecord]])

  return state.withMutations(map => {
    // Optimistically update the record
    map.set('raw', state.get('raw').merge(updatedRecordTuple))

    // Save previous version in case the update fails
    map.set('pendingUpdate', state.get('pendingUpdate').merge(previousRecordTuple))
  })
}

/**
 * The success action for the update reducer
 * @param  {Immutable.Map} state - current reducer state
 * @param  {Object} action - action object
 *
 * @return {Immutable.Map} - updated state
 */
 export const success = (state, action) => {

   const uid = action.record.get(action.uidField)

   // Remove the item pending update
   return state.deleteIn(['pendingUpdate', uid])
 }

/**
 * The error action for the update reducer
 * Reverts store change on failure
 * @param  {Immutable.Map} state - current reducer state
 * @param  {Object} action - action object
 *
 * @return {Immutable.Map} - updated state
 */
export const error = (state, action) => {

  const uid = action.record.get(action.uidField)

  // Create reverted record tuple
  // We have to create a tuple here in order to preserve the Integer typped keys
  const updatedRecord = Map([[uid, state.getIn(['pendingUpdate', uid])]])
  return state.withMutations(map => {

    // Revert changes
    map.set('raw', state.get('raw').merge(updatedRecord))

    // Remove the item pending update
    map.deleteIn(['pendingUpdate', uid])
  })
}

export default {
  start,
  success,
  error
}

@@ -308,32 +308,109 @@
 tion.uidField)%0A%0A
+  // Get previous record%0A  const previousRecord = state.getIn(%5B'raw', uid%5D)%0A%0A
   // Create upda
@@ -506,24 +506,35 @@
 ed keys%0A
-%0A  const
+  // If there is no
  previou
@@ -538,42 +538,35 @@
 ious
-R
+ r
 ecord 
-= state.getIn(%5B'raw', uid%5D)
+we add a new record
 %0A  c
@@ -583,34 +583,35 @@
 edRecord
-Tuple = Map(%5B%5Buid,
+ = previousRecord ?
  previou
@@ -642,63 +642,24 @@
 ord)
-%5D%5D)%0A%0A  // Create tuple for previous version of the item
+ : action.record
 %0A  c
@@ -659,32 +659,31 @@
 ord%0A  const 
-previous
+updated
 RecordTuple 
@@ -695,24 +695,23 @@
 (%5B%5Buid, 
-previous
+updated
 Record%5D%5D
@@ -851,24 +851,51 @@
 ordTuple))%0A%0A
+    if(previousRecord) %7B%0A  
     // Save 
@@ -936,16 +936,81 @@
 e fails%0A
+      const previousRecordTuple = Map(%5B%5Buid, previousRecord%5D%5D)%0A  
     map.
@@ -1085,16 +1085,22 @@
 Tuple))%0A
+    %7D%0A
   %7D)%0A%7D%0A%0A

add record to raw while updating if not already in story