import { Map } from 'immutable'
import NumberInput from '@instructure/quiz-number-input'

import QuizEntryBankEdit from '../presenter'

import Bank from '../../../../../../../common/records/Bank'
import QuizEntry from '../../../../../../../common/records/QuizEntry'

import EntrySave from '../../../../../../../common/components/resources/entry/EntrySave'

describe('QuizEntryBankEdit', () => {
  const fakeQuizEntry = new QuizEntry()
  const sandbox = sinon.createSandbox()
  const changeQuizEntryPointsStub = sandbox.stub()
  const changeQuizEntryPropertiesStub = sandbox.stub()
  const changeQuizEntryEntryStub = sandbox.stub()
  const clearModificationsStub = sandbox.stub()
  const switchOffEditingStub = sandbox.stub()
  const updateQuizEntryStub = sandbox.stub()
  const quizEntryBankProps = {
    displayPosition: 1,
    guid: 'myguid',
    pointsPossible: '0',
    workingBank: new Bank({ entryCount: 5 }),
    quizEntry: fakeQuizEntry,
    workingQuizEntry: fakeQuizEntry,
    changeQuizEntryPoints: changeQuizEntryPointsStub,
    changeQuizEntryProperties: changeQuizEntryPropertiesStub,
    changeQuizEntryEntry: changeQuizEntryEntryStub,
    clearModifications: clearModificationsStub,
    switchOffEditing: switchOffEditingStub,
    updateQuizEntry: updateQuizEntryStub
  }

  afterEach(() => {
    sandbox.resetHistory()
  })

  const testbed = createTestbed(QuizEntryBankEdit, quizEntryBankProps)
  const shallowtestbed = testbed.renderShallowly()

  it('renders the quiz entry bank', () => {
    const text = shallowtestbed.find('Text').first().render().text()
    expect(text).to.include('Number of questions')
  })

  it('renders the quiz entry bank with number of questions pulled and points possible', () => {
    const banktestbed = testbed.renderShallowly({
      pointsPossible: '121',
      quizEntry: new QuizEntry({
        properties: Map({ sampleNum: 2 })
      })
    })
    const text = banktestbed.find('Text').first().getElement().props.children
    expect(text).to.include('Number of questions')
    const numberInput = banktestbed.find(NumberInput).last()
    expect(numberInput.getElement().props.value).to.equal('121')
  })

  it('renders bank one input when questionSelection is set to all', () => {
    const output = testbed.renderShallowly({ questionSelection: 'all' })
    const inputs = output.find('Text')
    expect(inputs.length).to.eq(1)
  })

  it('renders bank both inputs when questionSelection is set to rand', () => {
    const output = testbed.renderShallowly({ questionSelection: 'rand' })
    const inputs = output.find('Text')
    expect(inputs.length).to.eq(2)
  })

  it('renders an error alert when the workingBank is archived', () => {
    const output = testbed.renderShallowly({ workingBank: new Bank({ archived: true }) })
    const alert = output.find('Alert')
    expect(alert.length).to.eq(1)
  })

  describe('clicks done', () => {
    it('submitHandler calls updateQuizEntry', () => {
      const entrySave = shallowtestbed.find(EntrySave)
      entrySave.props().submitHandler()
      expect(updateQuizEntryStub.called).to.be.true()
      expect(clearModificationsStub.called).to.be.true()
    })

    it('passes the guid to the EntrySave to ensure correct editable actions are called', () => {
      const entrySave = shallowtestbed.find(EntrySave)
      expect(entrySave.props().guid).to.eq(quizEntryBankProps.guid)
    })
  })

  it('Sets modification state for points possible', () => {
    const numberInput = shallowtestbed.find(NumberInput).last()
    numberInput.getElement().props.onChange({ target: { value: '6' } }, '6', '6')

    expect(changeQuizEntryPointsStub.calledWith('0', '6')).to.be.true()
  })

  it('Sets modification state for sampleNum', () => {
    const numberInput = testbed.renderShallowly({
      questionSelection: 'rand'
    }).find(NumberInput).first()

    numberInput.getElement().props.onChange({ target: { value: '9' } }, '9', '9')
    expect(changeQuizEntryPropertiesStub.calledWith('0', {
      selection: 'rand',
      sampleNum: '9'
    })).to.be.true()
  })
})
