import ReactTestUtils from 'react-dom/test-utils'
import { List } from 'immutable'
import InteractionType from 'quiz-interactions/lib/records/InteractionType'
import { withTestFeatures } from '../../../../../../util/featureCheck'
import { unsetFakeStore } from '../../../../../../../reduxStore'
import AddContentBody from '../presenter'

import {
  BUILD_TRAY_OPEN,
  BUILD_TRAY_POSITION,
  BUILD_TRAY_STIMULUS_ID
} from '@instructure/quiz-common/lib/constants'

describe('AddContentBody', () => {
  const createItemStub = sinon.stub()
  const createStimulusStub = sinon.stub()
  const onOpenBankTrayStub = sinon.stub()
  const onAddItemStub = sinon.stub()
  const screenreaderNotificationStub = sinon.stub()
  const setNextQuizEntryStub = sinon.stub()
  const setUiStub = sinon.stub()

  const fakeInteractionType = (name = 'choice') => new InteractionType({slug: name, name: name})
  const defaultProps = {
    allowStimulusCreation: true,
    createItem: createItemStub,
    createStimulus: createStimulusStub,
    editingQuizEntry: false,
    interactionTypes: List([
      fakeInteractionType('ONE'),
      fakeInteractionType('TWO'),
      fakeInteractionType('THREE')
    ]),
    onOpenBankTray: onOpenBankTrayStub,
    onAddItem: onAddItemStub,
    parentEntryId: 'parent123',
    position: 4,
    quizEntryWithErrorsShowing: null,
    quizId: 'quiz123',
    screenreaderNotification: screenreaderNotificationStub,
    setNextQuizEntry: setNextQuizEntryStub,
    setUi: setUiStub,
    showHeaderText: true,
    stimulusId: 'stimulus123'
  }

  const testbed = createTestbed(withContext(AddContentBody), defaultProps)

  beforeEach(() => {
    unsetFakeStore()

    createItemStub.resetHistory()
    createStimulusStub.resetHistory()
    onOpenBankTrayStub.resetHistory()
    onAddItemStub.resetHistory()
    screenreaderNotificationStub.resetHistory()
    setNextQuizEntryStub.resetHistory()
    setUiStub.resetHistory()
  })

  withTestFeatures(['stimulus'])

  it('displays the interaction types', () => {
    testbed.render()
    const html = testbed.rootNode.innerHTML
    expect(html.match(/ONE/)).to.exist()
    expect(html.match(/TWO/)).to.exist()
    expect(html.match(/THREE/)).to.exist()
  })

  it('displays an add stimulus button if allowStimulusCreation is true', () => {
    testbed.render()
    const html = testbed.rootNode.innerHTML
    expect(html.match(/Stimulus/)).to.be.not.be.null()
  })

  it('does not display an add stimulus button if allowStimulusCreation is false', () => {
    testbed.render({allowStimulusCreation: false})
    const html = testbed.rootNode.innerHTML
    expect(html.match(/Stimulus/)).to.be.null()
  })

  context('open bank tray button', () => {
    it('calls the callsbacks when the button is clicked', () => {
      testbed.render()
      const button = testbed.findChildrenBySelector('[data-automation="sdk-add-banked-content-button"]')[0]
      ReactTestUtils.Simulate.click(button)
      expect(onOpenBankTrayStub.called).to.be.true()
      expect(setUiStub.calledWith(BUILD_TRAY_OPEN, true)).to.be.true()
      expect(setUiStub.calledWith(BUILD_TRAY_POSITION, defaultProps.position)).to.be.true()
      expect(setUiStub.calledWith(BUILD_TRAY_STIMULUS_ID, defaultProps.parentEntryId)).to.be.true()
    })
  })

  context('addItem', () => {
    it('reports an screenreader error when errors are showing', () => {
      testbed.render({
        quizEntryWithErrorsShowing: { position: 10 }
      })
      const button = testbed.findChildrenByTagName('button')[1]
      button.click()
      expect(screenreaderNotificationStub.called).to.be.true()
    })

    it('does not report an screenreader error when errors are not showing', () => {
      testbed.render()
      const button = testbed.findChildrenByTagName('button')[1]
      button.click()
      expect(screenreaderNotificationStub.called).to.be.false()
    })

    it('calls setNextQuizEntry if an editingQuizEntry exists', () => {
      testbed.render({editingQuizEntry: {}})
      const button = testbed.findChildrenByTagName('button')[1]
      button.click()
      expect(setNextQuizEntryStub.called).to.be.true()
      const args = setNextQuizEntryStub.firstCall.args
      expect(args[1]).to.eq(defaultProps.quizId)
      expect(args[2]).to.eq(defaultProps.position)
      expect(args[3]).to.eq(defaultProps.stimulusId)
      expect(args[4]).to.eq(defaultProps.parentEntryId)
    })

    it('calls createItem otherwise', () => {
      testbed.render({editingQuizEntry: null})
      const button = testbed.findChildrenByTagName('button')[1]
      button.click()
      expect(createItemStub.called).to.be.true()
      const args = createItemStub.firstCall.args
      expect(args[0]).to.eq(defaultProps.quizId)
      expect(args[1]).to.eq(defaultProps.position)
      expect(args[2].id).to.eq(defaultProps.interactionTypes.get(0).id)
      expect(args[3]).to.eq(defaultProps.parentEntryId)
      expect(args[4]).to.eq(defaultProps.stimulusId)
    })
  })

  context('header', () => {
    it('shows a header when showHeaderText is true', () => {
      testbed.render()
      expect(testbed.rootNode.innerText.match(/Insert Content/)).to.not.be.null()
    })

    it('does not show a header when showHeaderText is true', () => {
      testbed.render({showHeaderText: false})
      expect(testbed.rootNode.innerText.match(/Insert Content/)).to.be.null()
    })
  })

  context('addStimulus', () => {
    it('calls setNextQuizEntry if editingQuizEntry exists', () => {
      testbed.render({editingQuizEntry: {}, allowStimulusCreation: true})
      const button = testbed.findChildrenByTagName('button')[4]
      button.click()
      expect(setNextQuizEntryStub.calledWith(
        null, defaultProps.quizId, defaultProps.position
      )).to.be.true()
    })

    it('calls createStimulus otherwise', () => {
      testbed.render({editingQuizEntry: null, allowStimulusCreation: true})
      const button = testbed.findChildrenByTagName('button')[4]
      button.click()
      expect(createStimulusStub.calledWith(
        defaultProps.quizId, defaultProps.position
      )).to.be.true()
    })

    it('calls onAddItem', () => {
      testbed.render({editingQuizEntry: null, allowStimulusCreation: true})
      const button = testbed.findChildrenByTagName('button')[4]
      button.click()
      expect(onAddItemStub.called).to.be.true()
    })
  })

  describe('test with connect', () => {
    shouldRenderComponent(
      testbed, {}, AddContentBody
    )
  })

  describe('a11y tests', () => {
    it('should meet a11y standards', (done) => {
      testbed.render()
      testbed.checkA11yStandards(done)
    })
  })
})
