import ReactTestUtils from 'react-dom/test-utils'
import { Map } from 'immutable'

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

import QuizTitle from '../presenter'
import QuizTitleEdit from '../../Edit'
import EditButton from '../../../editButton/EditButton'

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

import showStyles from '../../Show/styles.css'

describe('QuizTitle', () => {
  const quiz = new Quiz({id: '1', title: 'title'})
  const props = {
    changeQuizTitle: Function.prototype,
    quiz,
    workingQuiz: quiz,
    errorsShowing: Map(),
    hideError: Function.prototype,
    isEditing: false,
    onQuizUpdated: Function.prototype,
    saveQuizChange: Function.prototype,
    screenreaderNotification: Function.prototype,
    scrollKey: 'scrollKey',
    showError: Function.prototype,
    switchOffEditing: Function.prototype,
    switchOnEditing: Function.prototype
  }

  const testbed = createTestbed(withContext(QuizTitle), props)

  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 title edit if isEditing is true', () => {
    testbed.render({isEditing: true})

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

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

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

  it('handleInput should switchOffEditing if enter was hit', () => {
    const switchOffEditingStub = sinon.stub()
    testbed.render({
      isEditing: true,
      switchOffEditing: switchOffEditingStub
    })

    const titleInput = testbed.findChildByType(QuizTitleEdit)

    ReactTestUtils.Simulate.keyDown(titleInput.input, {key: 'q', keyCode: 81, which: 81})
    expect(switchOffEditingStub.called).to.be.false()

    ReactTestUtils.Simulate.keyDown(titleInput.input, {key: 'Enter', keyCode: 13, which: 13})
    expect(switchOffEditingStub.calledOnce).to.be.true()
  })

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

    const titleEdit = testbed.findChildByType(QuizTitleEdit)
    titleEdit.props.saveAndPreview()

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

  it('should call onQuizUpdated prop on save', () => {
    const onQuizUpdatedSpy = sinon.spy()
    testbed.render({
      onQuizUpdated: onQuizUpdatedSpy,
      isEditing: true
    })

    const titleEdit = testbed.findChildByType(QuizTitleEdit)
    titleEdit.props.saveAndPreview()

    expect(onQuizUpdatedSpy).to.have.been.calledWith({id: '1', title: 'title'})
  })

  it('should be able to persist modifications to title', () => {
    const saveQuizChangeStub = sinon.stub()
    const workingQuiz = {
      title: 'the working title',
      errorsFor: Function.prototype,
      isValid: () => true
    }
    const quiz = new Quiz({
      id: '1'
    })

    testbed.render({
      quiz,
      workingQuiz,
      isEditing: true,
      saveQuizChange: saveQuizChangeStub
    })

    // easiest way to get cancel
    const titleEdit = testbed.findChildByType(QuizTitleEdit)

    titleEdit.props.saveAndPreview()
    const stubArgs = saveQuizChangeStub.getCall(0).args

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

  it('passes scrollKey to EditButton', () => {
    testbed.render()
    const editButton = testbed.findChildByType(EditButton)
    expect(editButton.props.scrollKey).to.equal(props.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: 'Title switched to edit mode.',
    turnedOff: 'Title edit mode off.'
  })

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