// Let's say we have three events:
// CONNECTED
// NEW ITEM IN ARRAY
// DELETED ITEM IN ARRAY
// We're a doing a chat with deletion features

// We have an API which is sync'd with our backend.

const API = new SuperAPI()

// We want constants to start

const initialConnectionState = API.initialTree.connection  // This is the initial tree.
const initialState = {
  connection: API.initialTree.connection,
  messages: API.initialTree.messages
}

const CONNECTED = 'socket@@CONNECTED'
const CONNECTION_ERROR = 'socket@@CONNECTION_ERROR'
const DISCONNECTED = 'socket@@DISCONNECTED'

const SEND_MESSAGE = 'chat@@SEND_MESSAGE'
const RECEIVE_MESSAGE = 'chat@@RECEIVE_MESSAGE'
const DELETE_MESSAGE = 'chat@@DELETE_MESSAGE'
const RECEIVE_MESSAGE_DELETION = 'chat@@RECEIVE_MESSAGE_DELETION'

// Now, actions creators

const connected = createAction(CONNECTED)
const disconnected = createAction(DISCONNECTED)
const connectionError = createAction(CONNECTION_ERROR)

const initiateConnection = () => dispatch => {
  return api.connect()
  .then(() => dispatch(connected()), error => dispatch(connectionError(error)))
}

const disconnect = () => dispatch => {
  api.disconnect()
  dispatch(disconnected())
}

const sendMessage = message => dispatch => {
  api.messages.append(message)
  .then(() => {
    dispatch(messageSent(message))
  }, error => dispatch(failedToSendMessage(message)))
}

api.on('RECEIVE_MESSAGE', message => {
  receiveMessage(message)
})

// Reducer

function reduceConnection (state = initialState.connection, action) {
  if (action.type === DISCONNECTED) {
    return {
      ...state,
      connected: false
    }
  }
  if (action.type === CONNECTED) {
    return {
      ...state,
      connected: true
    }
  }
  if (action.type === CONNECTION_ERROR) {
    return {
      ...state,
      connectionError: action.error
    }
  }
  return state
}

function reduceMessages (state = initialState.messages, action) {
  if (action.type === RECEIVE_MESSAGE) {
    return {
      ...state,
      messages: state.messages.concat([action.payload.message])
    }
  }
  
  if (action.type === RECEIVE_MESSAGE_DELETION) {
    return {
      ...state,
      messages: state.messages.filter(message => message.id !== action.payload.deletedMessage.id)
    }
  }
  
  if (action.type === SENT_MESSAGE) {
    return {
      ...state,
      messages: state.messages.concat([action.payload.message]),
      messageCountSent: state.messageCountSent + 1 // This is absolutely useless, but we're doing an example.
    }
  }
  
  return state
}

export default combineReducers({
  connection: reduceConnection,
  messages: reduceMessages
})