import { Map } from 'immutable'

import toggleEditingTests from '../../../__tests__/toggleEditingTests'

import QuizInstructions from '../presenter'
import QuizInstructionsEdit from '../../Edit'
import EditButton from '../../../editButton/EditButton'
import showStyles from '../../Show/styles.css'

import Quiz from '../../../../../../../common/records/Quiz'

describe('Building QuizInstructions', () => {
  const quiz = new Quiz({id: '3'})
  const scrollKey = 'scrollKey'
  const testbed = createTestbed(withContext(QuizInstructions), {
    clearModifications: () => {},
    persistModification: () => {},
    saveQuizChange: () => {},
    screenreaderNotification: () => {},
    changeQuizInstructions: () => {},
    isEditin: false,
    quiz,
    workingQuiz: Map(),
    switchOffEditing: () => {},
    switchOnEditing: () => {},
    scrollKey
  })

  it('renders a non-navigable tab index for scroll focus', () => {
    testbed.render()
    const subject = testbed.findChildrenByTagNameAndAttribute(
      'div', 'tabindex', '-1'
    )[0]
    expect(subject).to.be.ok()
  })

  it('should render quiz instructions edit if isEditing is true', () => {
    testbed.render({isEditing: true})

    expect(testbed.findChildrenByType(QuizInstructionsEdit)).to.not.be.empty()
  })

  it('should render quiz instructions preview if isEditing is false', () => {
    testbed.render({isEditing: false})

    expect(testbed.findChildrenByClass(showStyles.instructionsShowText)).to.not.be.empty()
  })

  it('should call switchOffEditing and clearModifications on save', () => {
    const clearModificationsSpy = sinon.spy()
    const switchOffEditingSpy = sinon.spy()
    testbed.render({
      clearModifications: clearModificationsSpy,
      switchOffEditing: switchOffEditingSpy,
      isEditing: true
    })

    const instructionsEdit = testbed.findChildByType(QuizInstructionsEdit)
    instructionsEdit.props.saveAndPreview()

    expect(clearModificationsSpy).to.have.been.calledOnce()
    expect(switchOffEditingSpy).to.have.been.calledOnce()
  })

  it('should not pass null instructions into the rce', () => {
    testbed.render({
      isEditing: true,
      quiz: new Quiz({instructions: null, id: '3'})
    })

    const instructions = testbed.findChildByType(QuizInstructions)

    expect(instructions.workingInstructions()).to.be.equal('')
  })

  it('should dispatch a change instructions action on the right quiz', () => {
    const changeInstructionsStub = sinon.stub()
    testbed.render({
      isEditing: true,
      quiz: new Quiz({instructions: 'the original quiz desc', id: '3'}),
      changeQuizInstructions: changeInstructionsStub,
      saveQuizChange: () => {}
    })

    const instructionsEdit = testbed.findChildByType(QuizInstructionsEdit)
    instructionsEdit.props.onInputChange({}, 'some value here?')
    const stubArgs = changeInstructionsStub.getCall(0).args[0]

    expect(stubArgs[0]).to.be.equal('3')
  })

  it('should be able to persist modifications to instructions ', () => {
    const saveQuizChangeStub = sinon.stub()

    const moddedQuiz = new Quiz({id: '3', instructions: 'the original quiz desc'})
    sinon.stub(moddedQuiz, 'getWorkingInstance').returns(
      moddedQuiz.merge({instructions: 'the working instructions'})
    )

    testbed.render({
      isEditing: true,
      quiz: moddedQuiz,
      clearModifications: () => {},
      saveQuizChange: saveQuizChangeStub,
      changeQuizInstructions: () => {}
    })

    // easiest way to get saveAndPreview
    const instructionsEdit = testbed.findChildByType(QuizInstructionsEdit)
    instructionsEdit.props.saveAndPreview()
    const stubArgs = saveQuizChangeStub.getCall(0).args

    expect(stubArgs[0].get('instructions')).to.be.equal('the working instructions')
  })

  it('passes scrollKey to EditButton', () => {
    testbed.render()
    const editButton = testbed.findChildByType(EditButton)
    expect(editButton.props.scrollKey).to.equal(scrollKey)
  })

  it('does not include edit button when editing', () => {
    testbed.render({ isEditing: true })
    const editButtons = testbed.findChildrenByType(EditButton)
    expect(editButtons).to.have.length(0)
  })

  toggleEditingTests(testbed, {
    turnedOn: 'Instructions switched to edit mode. Navigate down to access text editor.',
    turnedOff: 'Instructions edit mode off.'
  })

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