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

import IconBank from '@instructure/ui-icons/lib/Line/IconBank'

import { wrapInDragAndDropTestContext } from '../../../../../../../tests/util/dndTestUtils'
import ConnectedQuizEntryShow from '../index'
import QuizEntryShow, { QuizEntryShowRaw } from '../presenter'
import ActionButtons from '../../../ActionButtons'
import Item from '../../../../../../common/records/Item'
import QuizEntry from '../../../../../../common/records/QuizEntry'
import Bank from '../../../../../../common/records/Bank'
import styles from '../styles.css'
import overlayStyles from '../../../../../../common/components/shared/overlay/styles.css'

import PositionBox from '../../../../../../common/components/resources/positionBox/PositionBox'

describe('QuizEntryShow', () => {
  const QuizEntryShowWithContext = withContext(QuizEntryShow)

  const moveQuizEntryStub = sinon.stub()
  const moveTemporaryQuizEntryStub = sinon.stub()
  const removeQuizEntryStub = sinon.stub()
  const screenreaderNotificationStub = sinon.stub()
  const switchOnEditingStub = sinon.stub()

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

  const item = new Item({id: 66, title: 'The Title'})
  const bank = new Bank({id: '1', entryCount: 120})

  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 defaultProps = {
    moveQuizEntry: moveQuizEntryStub,
    moveTemporaryQuizEntry: moveTemporaryQuizEntryStub,
    removeQuizEntry: removeQuizEntryStub,
    screenreaderNotification: screenreaderNotificationStub,
    switchOnEditing: switchOnEditingStub,
    errorsAreShowing: Map(),
    quizEntry,
    entry: item,
    displayPosition: 3,
    quizEntries: quizEntries,
    scrollKey: 'scrollKey',
    editQuizEntryToggle: false
  }

  const testbed = createTestbed(wrapInDragAndDropTestContext(QuizEntryShowWithContext), defaultProps)

  beforeEach(() => {
    moveQuizEntryStub.resetHistory()
    moveTemporaryQuizEntryStub.resetHistory()
    removeQuizEntryStub.resetHistory()
    screenreaderNotificationStub.resetHistory()
    switchOnEditingStub.resetHistory()
  })

  shouldRenderComponent(
    testbed, {}, QuizEntryShowWithContext
  )

  it('renders the title', () => {
    testbed.render()
    expect(testbed.rootNode.innerText.match(/The Title/)).to.exist()
  })

  it('renders a bank entry', () => {
    const qe = quizEntry.set('entryType', 'Bank')
    sinon.stub(qe, 'getEntry').returns(bank)

    testbed.render({quizEntry: qe})
    const elem = testbed.findChildrenByType(IconBank)[0]
    expect(elem).to.not.be.undefined()
  })

  context('item-type entry', () => {
    it('renders points possible', () => {
      testbed.render()
      const pointsPossible = testbed.findChildrenByClass(styles.points)[0].innerText
      expect(pointsPossible).to.eq('12 points')
    })

    it('defaults points possible to 0', () => {
      testbed.render({quizEntry: quizEntry.set('pointsPossible', void 0)})
      const pointsPossible = testbed.findChildrenByClass(styles.points)[0].innerText
      expect(pointsPossible).to.eq('0 points')
    })
  })

  it('switches to editing mode on click', () => {
    testbed.render()
    const header = testbed.findChildrenByClass(overlayStyles.overlay)[0]
    ReactTestUtils.Simulate.click(header)
    expect(switchOnEditingStub.called).to.be.true()
    expect(screenreaderNotificationStub.called).to.be.true()
  })

  it('does not switch to edit mode if there are errors on another quiz entry', () => {
    testbed.render({quizEntryWithErrorsShowing: {position: 1}})
    const header = testbed.findChildrenByClass(overlayStyles.overlay)[0]
    ReactTestUtils.Simulate.click(header)
    expect(switchOnEditingStub.called).to.be.false()
    expect(screenreaderNotificationStub.called).to.be.false()
  })

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

  describe('display position', () => {
    it('renders the displayPosition rather than the quizEntry position', () => {
      testbed.render()
      const box = testbed.findChildrenByType(PositionBox)[0]
      expect(box.props.position).to.eql(`${defaultProps.displayPosition}`)
    })
  })

  describe('#shouldDisableDragHandle', () => {
    const runTest = (position, quizEntries, expected) => {
      testbed.render({
        quizEntry: quizEntry.set('position', position),
        quizEntries
      })
      const subject = testbed.findChildByType(QuizEntryShowRaw)
      expect(subject.shouldDisableDragHandle()).to.eq(expected)
    }

    it('is true if there is only one item', () => {
      runTest(1, List([quizEntry]), true)
    })

    it('is false if there are successor items', () => {
      runTest(1, List([quizEntry, quizEntry2]), false)
    })

    it('is false if there are predecessor items', () => {
      runTest(2, List([quizEntry1, quizEntry]), false)
    })
  })

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

  describe('test with connect', () => {
    const connectedTestbed = createTestbed(
      wrapInDragAndDropTestContext(withContext(ConnectedQuizEntryShow)),
      defaultProps
    )

    shouldRenderComponent(
      connectedTestbed, {}, QuizEntryShow
    )
  })
})
