import { fromJS } from 'immutable'
import { expect } from 'chai'

import quizEntriesReducer from '../quizEntries'

import {
  addQuizEntries,
  addQuizEntry,
  deleteQuizEntry,
  deleteStimulusEntry,
  moveQuizEntry
} from '../../actions/quizEntries'

describe('quizEntries reducer', () => {
  describe('addQuizEntries', () => {
    it('should add quiz entry to state', () => {
      const initialState = fromJS({})
      const action = addQuizEntries([{id: '1', pointsPossible: '5'}])
      const nextState = quizEntriesReducer(initialState, action)

      const nextQuizEntryPoints = nextState.get('1').get('pointsPossible')
      expect(nextQuizEntryPoints).to.equal('5')
    })

    it('does not merge new with old state', () => {
      const initialState = fromJS({2: {id: '2', pointsPossible: '5'}})
      const action = addQuizEntries([{id: '1', pointsPossible: '5'}])
      const nextState = quizEntriesReducer(initialState, action)

      expect(nextState).to.equal(fromJS({1: {id: '1', pointsPossible: '5'}}))
    })
  })

  describe('addQuizEntry', () => {
    it('should add quiz entry to state', () => {
      const initialState = fromJS({})
      const action = addQuizEntry({id: '1', pointsPossible: '5'})
      const nextState = quizEntriesReducer(initialState, action)

      const nextQuizEntryPoints = nextState.get('1').get('pointsPossible')
      expect(nextQuizEntryPoints).to.equal('5')
    })

    it('does merge new with old state', () => {
      const initialState = fromJS({2: {id: '2', pointsPossible: '5'}})
      const action = addQuizEntry({id: '1', pointsPossible: '5'})
      const nextState = quizEntriesReducer(initialState, action)

      expect(nextState).to.equal(fromJS({
        1: {id: '1', pointsPossible: '5'},
        2: {id: '2', pointsPossible: '5'}
      }))
    })
  })

  describe('deleteQuizEntry', () => {
    it('removes the quiz entry from state', () => {
      const initialState = fromJS({
        '1': { id: '1' },
        '2': { id: '2' }
      })
      const action = deleteQuizEntry('1')
      const nextState = quizEntriesReducer(initialState, action)

      expect(nextState).to.equal(fromJS({
        '2': { id: '2' }
      }))
    })

    it('updates positions', () => {
      const initialState = fromJS({
        '1': { id: '1', position: 1 },
        '2': { id: '2', position: 2 },
        '3': { id: '3', position: 3 }
      })
      const action = deleteQuizEntry('2')
      const nextState = quizEntriesReducer(initialState, action)

      expect(nextState).to.equal(fromJS({
        '1': { id: '1', position: 1 },
        '3': { id: '3', position: 2 }
      }))
    })
  })

  describe('deleteStimulusEntry', () => {
    it('removes the stimulus entry from state', () => {
      const initialState = fromJS({
        '1': { id: '1', stimulusQuizEntryId: '' },
        '2': { id: '2', stimulusQuizEntryId: '' }
      })
      const action = deleteStimulusEntry('1')
      const nextState = quizEntriesReducer(initialState, action)

      expect(nextState).to.equal(fromJS({
        '2': { id: '2', stimulusQuizEntryId: '' }
      }))
    })

    it('removes the given child entries from state', () => {
      const initialState = fromJS({
        '1': { id: '1', stimulusQuizEntryId: '' },
        '2': { id: '2', stimulusQuizEntryId: '1' },
        '3': { id: '3', stimulusQuizEntryId: '' }
      })
      const action = deleteStimulusEntry('1', ['2'])
      const nextState = quizEntriesReducer(initialState, action)

      expect(nextState).to.equal(fromJS({
        '3': { id: '3', stimulusQuizEntryId: '' }
      }))
    })

    it('disassociates child entries from the stimulus', () => {
      const initialState = fromJS({
        '1': { id: '1', stimulusQuizEntryId: '' },
        '2': { id: '2', stimulusQuizEntryId: '1' }
      })
      const action = deleteStimulusEntry('1')
      const nextState = quizEntriesReducer(initialState, action)

      expect(nextState).to.equal(fromJS({
        '2': { id: '2', stimulusQuizEntryId: '' }
      }))
    })

    it('updates positions', () => {
      const initialState = fromJS({
        '1': { id: '1', position: 1, stimulusQuizEntryId: '' },
        '2': { id: '2', position: 2, stimulusQuizEntryId: '' },
        '3': { id: '3', position: 3, stimulusQuizEntryId: '2' },
        '4': { id: '4', position: 4, stimulusQuizEntryId: '' }
      })
      const action = deleteStimulusEntry('2', ['3'])
      const nextState = quizEntriesReducer(initialState, action)

      expect(nextState).to.equal(fromJS({
        '1': { id: '1', position: 1, stimulusQuizEntryId: '' },
        '4': { id: '4', position: 2, stimulusQuizEntryId: '' }
      }))
    })
  })

  describe('moveQuizEntry', () => {
    it('updates stimulusQuizEntryId', () => {
      const initialState = fromJS({
        '1': { id: '1', position: 1, stimulusQuizEntryId: '' },
        '2': { id: '2', position: 2, stimulusQuizEntryId: '' }
      })
      const action = moveQuizEntry('2', 2, '1')
      const nextState = quizEntriesReducer(initialState, action)

      expect(nextState).to.equal(fromJS({
        '1': { id: '1', position: 1, stimulusQuizEntryId: '' },
        '2': { id: '2', position: 2, stimulusQuizEntryId: '1' }
      }))
    })

    it('updates positions when moving an entry up', () => {
      const initialState = fromJS({
        '1': { id: '1', position: 1, stimulusQuizEntryId: '' },
        '2': { id: '2', position: 2, stimulusQuizEntryId: '' },
        '3': { id: '3', position: 3, stimulusQuizEntryId: '' },
        '4': { id: '4', position: 4, stimulusQuizEntryId: '' },
        '5': { id: '5', position: 5, stimulusQuizEntryId: '' }
      })
      const action = moveQuizEntry('4', 2, '')
      const nextState = quizEntriesReducer(initialState, action)

      expect(nextState).to.equal(fromJS({
        '1': { id: '1', position: 1, stimulusQuizEntryId: '' },
        '2': { id: '2', position: 3, stimulusQuizEntryId: '' },
        '3': { id: '3', position: 4, stimulusQuizEntryId: '' },
        '4': { id: '4', position: 2, stimulusQuizEntryId: '' },
        '5': { id: '5', position: 5, stimulusQuizEntryId: '' }
      }))
    })

    it('updates positions when moving an entry down', () => {
      const initialState = fromJS({
        '1': { id: '1', position: 1, stimulusQuizEntryId: '' },
        '2': { id: '2', position: 2, stimulusQuizEntryId: '' },
        '3': { id: '3', position: 3, stimulusQuizEntryId: '' },
        '4': { id: '4', position: 4, stimulusQuizEntryId: '' },
        '5': { id: '5', position: 5, stimulusQuizEntryId: '' }
      })
      const action = moveQuizEntry('2', 4, '')
      const nextState = quizEntriesReducer(initialState, action)

      expect(nextState).to.equal(fromJS({
        '1': { id: '1', position: 1, stimulusQuizEntryId: '' },
        '2': { id: '2', position: 4, stimulusQuizEntryId: '' },
        '3': { id: '3', position: 2, stimulusQuizEntryId: '' },
        '4': { id: '4', position: 3, stimulusQuizEntryId: '' },
        '5': { id: '5', position: 5, stimulusQuizEntryId: '' }
      }))
    })
  })
})
