import ReactDOM from 'react-dom'
import { List, fromJS } from 'immutable'
import TextInput from '@instructure/ui-forms/lib/components/TextInput'

import QuizEntryEditHeader from '../index'
import Item from '../../../../../../../common/records/Item'
import QuizEntry from '../../../../../../../common/records/QuizEntry'
import styles from '../styles.css'

describe('QuizEntryEditHeader', () => {
  const sandbox = sinon.createSandbox()

  const changeItemTitleStub = sandbox.stub()
  const changeQuizEntryEntryStub = sandbox.stub()
  const changeQuizEntryPointsStub = sandbox.stub()
  const clearModificationsStub = sandbox.stub()
  const clearTemporaryItemStub = sandbox.stub()
  const cloneQuizEntryStub = sandbox.stub()
  const connectDragSourceStub = sandbox.stub()
  const createItemStub = sandbox.stub().returns(Promise.resolve({ id: '2' }))
  const createQuizEntryStub = sandbox.stub().returns(Promise.resolve({ id: '56' }))
  const hideErrorStub = sandbox.stub()
  const moveQuizEntryStub = sandbox.stub()
  const moveTemporaryQuizEntryStub = sandbox.stub()
  const openModalStub = sandbox.stub()
  const removeQuizEntryStub = sandbox.stub()
  const screenreaderNotificationStub = sandbox.stub()
  const setUiStub = sandbox.stub()
  const showErrorStub = sandbox.stub()
  const switchOffEditingStub = sandbox.stub()
  const updateItemStub = sandbox.stub().resolves()
  const updateQuizEntryStub = sandbox.stub().resolves()

  const workingQuizEntry = new QuizEntry({
    id: '55',
    pointsPossible: 3999
  })
  workingQuizEntry.isValid = () => true

  const quizEntry = new QuizEntry({
    id: '55',
    entryType: 'Item',
    entryId: 66,
    pointsPossible: 12,
    position: 3
  })

  const quizEntry1 = new QuizEntry({ position: 1 })
  const quizEntry2 = new QuizEntry({ position: 2 })
  const quizEntry4 = new QuizEntry({ position: 4 })
  const quizEntry5 = new QuizEntry({ position: 5 })
  const quizEntries = List([quizEntry1, quizEntry2, quizEntry, quizEntry4, quizEntry5])

  const workingItem = new Item({
    id: '1',
    properties: {
      varyPointsByAnswer: false
    }
  })
  workingItem.isValid = () => true
  workingItem.getErrors = () => fromJS({})
  workingItem.errorsFor = () => fromJS({})

  const item = new Item({ id: '66', title: 'some title' })

  const defaultProps = {
    changeItemTitle: changeItemTitleStub,
    changeQuizEntryEntry: changeQuizEntryEntryStub,
    changeQuizEntryPoints: changeQuizEntryPointsStub,
    clearModifications: clearModificationsStub,
    clearTemporaryItem: clearTemporaryItemStub,
    cloneQuizEntry: cloneQuizEntryStub,
    connectDragSource: connectDragSourceStub,
    createItem: createItemStub,
    createQuizEntry: createQuizEntryStub,
    hideError: hideErrorStub,
    moveQuizEntry: moveQuizEntryStub,
    moveTemporaryQuizEntry: moveTemporaryQuizEntryStub,

    displayPosition: 3,
    entry: item,
    guid: 'guid123',
    isOccluded: false,
    moveToPosition: () => {},
    name: 'This Will Not Always Be An Interaction Type Name So Please Do Not Assume It Is',
    openModal: openModalStub,
    quizEntries: quizEntries,
    quizEntry,
    quizId: '99',
    removeQuizEntry: removeQuizEntryStub,
    screenreaderNotification: screenreaderNotificationStub,
    setUi: setUiStub,
    showError: showErrorStub,
    switchOffEditing: switchOffEditingStub,
    updateItem: updateItemStub,
    updateQuizEntry: updateQuizEntryStub,
    withConfirm: () => {},
    workingEntry: workingItem
  }

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

  beforeEach(() => {
    quizEntry.getWorkingInstance = () => workingQuizEntry
    item.getWorkingInstance = () => workingItem

    sandbox.resetHistory()
  })

  shouldRenderComponent(
    testbed, {}, QuizEntryEditHeader
  )

  it('renders the position from props (not from item record)', () => {
    const positionProp = 8
    testbed.render({ displayPosition: positionProp })
    const positionNode = testbed.findChildrenByClass(styles.leftHeader)[0]
    expect(positionNode.innerText).to.include(`${positionProp}`)
  })

  it('renders the name prop in header', () => {
    testbed.render()
    const header = testbed.findChildrenByClass(styles.header)[0]
    expect(testbed.getText(header))
      .to.include('This Will Not Always Be An Interaction Type Name So Please Do Not Assume It Is')
  })

  describe('title change', () => {
    it('calls changeItemTitle when the title is changed', () => {
      testbed.render()
      const titleInput = ReactDOM.findDOMNode(testbed.findChildByType(TextInput))
      testbed.change(titleInput.querySelector('input'), 'new title')
      expect(changeItemTitleStub).to.have.been.called()
    })

    it('shows the workingItem title in the title input', () => {
      testbed.render({ workingEntry: item })
      const titleInput = ReactDOM.findDOMNode(testbed.findChildByType(TextInput))
      expect(titleInput.querySelector('input').value).to.equal('some title')
    })
  })

  describe('a11y tests', () => {
    it('should meet a11y standards', (done) => {
      testbed.render()
      testbed.checkA11yStandards(done, { ignores: ['label', 'label-title-only'] })
    })
  })

  describe('initialFocusId is not set', () => {
    it('titleRef should be focused', (done) => {
      testbed.render()
      const subject = testbed.findChildByType(QuizEntryEditHeader)
      setTimeout(() => {
        expect(subject.titleRef.focused).to.be.true()
        done()
      }, 300)
    })
  })

  describe('initialFocusId is set', () => {
    it('titleRef should not be focused', (done) => {
      testbed.render(Object.assign(
        {},
        defaultProps,
        { initialFocusId: 'abcdefg' }
      ))
      const subject = testbed.findChildByType(QuizEntryEditHeader)
      setTimeout(() => {
        expect(subject.titleRef.focused).to.be.false()
        done()
      }, 300)
    })
  })

  describe('initialFocusId is not set', () => {
    it('titleRef should be focused', (done) => {
      testbed.render()
      const subject = testbed.findChildByType(QuizEntryEditHeader)
      setTimeout(() => {
        expect(subject.titleRef.focused).to.be.true()
        done()
      }, 300)
    })
  })

  describe('initialFocusId is set', () => {
    it('titleRef should not be focused', (done) => {
      testbed.render(
        Object.assign(
          {},
          defaultProps,
          { initialFocusId: 'abcdefg' }
        ))
      const subject = testbed.findChildByType(QuizEntryEditHeader)
      setTimeout(() => {
        expect(subject.titleRef.focused).to.be.false()
        done()
      }, 300)
    })
  })
})
