import InteractionType from 'quiz-interactions/lib/records/InteractionType'

import createTestbed from '../../../../../tests/util/shallowTestbed'
import Item from '../../../../common/records/Item'
import Stimulus from '../../../../common/records/Stimulus'
import BankEntry from '../../../../common/records/BankEntry'

import CopyMoveBankEntryModal from '../../CopyMoveBankEntryModal'
import BankEntryRow from '../presenter'
import styles from '../styles.css'
import { SET_EDIT_BUTTON_FOCUS } from '@instructure/quiz-common/lib/constants'

describe('BankEntryRow', () => {
  const toggleExpandedStub = sinon.stub()
  const setUiStub = sinon.stub()
  const type = new InteractionType({ name: 'Multiple Choice', slug: 'choice' })
  const item = new Item({
    id: '666',
    title: 'Tough Color Question',
    itemBody: 'Which color is happiest?',
    scoringData: {
      value: 'id'
    }
  })
  sinon.stub(item, 'getInteractionType').returns(type)
  const bankEntry = new BankEntry({
    id: '1',
    entry: item,
    entryType: 'Item',
    updatedAt: new Date()
  })
  sinon.stub(bankEntry, 'getEntry').returns(item)
  const addEntryToQuizStub = sinon.stub().resolves()
  const createItemStub = sinon.stub().returnsArg(0)
  const openModal = sinon.stub()
  const navigateBankEntryStub = sinon.stub()
  const withConfirmStub = sinon.stub()
  const removeBankEntryStub = sinon.stub()
  const screenreaderNotificationStub = sinon.stub()

  const testbed = createTestbed(BankEntryRow, {
    addEntryToQuiz: addEntryToQuizStub,
    bankEntry,
    createItem: createItemStub,
    isExpanded: false,
    toggleExpanded: toggleExpandedStub,
    openModal: openModal,
    navigateToBankEntry: navigateBankEntryStub,
    screenreaderNotification: screenreaderNotificationStub,
    removeBankEntry: removeBankEntryStub,
    withConfirm: withConfirmStub,
    setUi: setUiStub,
    useBankTags: false
  })

  afterEach(() => {
    addEntryToQuizStub.resetHistory()
    toggleExpandedStub.resetHistory()
    setUiStub.resetHistory()
    createItemStub.resetHistory()
    openModal.resetHistory()
    navigateBankEntryStub.resetHistory()
    withConfirmStub.resetHistory()
    removeBankEntryStub.resetHistory()
    screenreaderNotificationStub.resetHistory()
  })

  it('should render entry', () => {
    testbed.render({}, null, {disableLifecycleMethods: true})
    expect(testbed.getText('Heading')).to.include('Multiple Choice')
    expect(testbed.getText('Heading')).to.include('Item Tough Color Question')
    expect(testbed.getText('RichContentRenderer')).to.include('Which color is happiest?')
  })

  describe('addToQuiz', () => {
    it('should render "add to quiz" button only when action creator is provided', () => {
      testbed.render({ addEntryToQuiz: void 0 }, null, {disableLifecycleMethods: true})
      expect(testbed.find(`.${styles.addButton}`).length).to.eq(0)
      testbed.render({}, null, {disableLifecycleMethods: true})
      expect(testbed.find(`.${styles.addButton}`).length).to.eq(1)
    })

    it('should render disabled "add to quiz" button if is stimulus and adding to stimulus', () => {
      const bankEntry = new BankEntry({ entryType: 'Stimulus' })
      sinon.stub(bankEntry, 'getEntry').returns(new Stimulus())
      testbed.render({
        stimulusId: 5,
        bankEntry
      }, null, {disableLifecycleMethods: true})
      const button = testbed.find(`.${styles.addButton}`).first()
      expect(button.props().children.props.disabled).to.be.true()
    })

    it('should render enabled "add to quiz" button if is item and adding to stimulus', () => {
      testbed.render({
        stimulusId: 5
      }, null, {disableLifecycleMethods: true})
      const button = testbed.find(`.${styles.addButton}`).first()
      expect(button.props().children.props.disabled).to.be.false()
    })

    it('should render enabled "add to quiz" button if is stimulus, but not adding to stimulus', () => {
      const bankEntry = new BankEntry({ entryType: 'Stimulus' })
      sinon.stub(bankEntry, 'getEntry').returns(new Stimulus())
      testbed.render({
        bankEntry
      }, null, {disableLifecycleMethods: true})
      const button = testbed.find(`.${styles.addButton}`).first()
      expect(button.props().children.props.disabled).to.be.false()
    })

    it('should call "add to quiz" when quiz id is provided', () => {
      testbed.render({ activeQuizId: '876' }, null, {disableLifecycleMethods: true})
      testbed.click(testbed.find(`.${styles.addButton} Button`).first())
      expect(addEntryToQuizStub).to.have.been.calledWith('876', '1', 'BankEntry', sinon.match({ points_possible: 1 }))
    })

    it('calls addEntryToQuiz and alerts the screenreader', (done) => {
      testbed.render({ activeQuizId: '876' }, null, {disableLifecycleMethods: true})
      testbed.click(testbed.find(`.${styles.addButton} Button`).first())
      expect(addEntryToQuizStub).to.have.been.called()
      setTimeout(() => {
        expect(screenreaderNotificationStub).to.have.been.called()
        done()
      })
    })
  })

  describe('expandable', () => {
    it('should read correctly', () => {
      testbed.render({}, null, {disableLifecycleMethods: true})
      expect(testbed.find('ExpandButton').prop('title')).to.eq('Expand Item details')
      testbed.render({ isExpanded: true }, null, {disableLifecycleMethods: true})
      expect(testbed.find('ExpandButton').prop('title')).to.eq('Collapse Item details')
    })

    it('clicking down arrow should trigger expand toggle', () => {
      testbed.render({}, null, {disableLifecycleMethods: true})
      testbed.click(testbed.find('ExpandButton'))
      expect(toggleExpandedStub).to.be.calledOnce()
    })

    it('should render entry details', () => {
      testbed.render({ isExpanded: true }, null, {disableLifecycleMethods: true})
      const output = testbed.getText(`.${styles.footer}`)
      expect(output).to.include('Last Update')
    })
  })

  describe('CopyMoveBankEntryModal', () => {
    it('clicking move/copy button should open modal', () => {
      testbed.render({}, null, {disableLifecycleMethods: true})
      testbed.click(testbed.find('Button').at(2))
      expect(openModal).to.have.been.calledWith('COPY_MOVE_BANK_ENTRY_MODAL:Item:666')
    })

    it('should create a new entry when requested', async () => {
      testbed.render({}, null, {disableLifecycleMethods: true})
      const entry = await testbed.find(CopyMoveBankEntryModal).prop('createEntry')()
      expect(createItemStub).to.have.been.calledWith(item)
      expect(entry).to.eq(item)
    })
  })

  describe('deleteBankEntry', () => {
    it('clicking trash button should ask to remove bank entry', () => {
      testbed.render({}, null, {disableLifecycleMethods: true})
      testbed.click(testbed.find('Button').at(3))
      expect(withConfirmStub).to.have.been.called()
      withConfirmStub.getCalls()[0].args[0]()
      expect(removeBankEntryStub).to.have.been.called()
    })
  })

  describe('edit bank entry', () => {
    it('clicking edit button should navigate to bank entry', () => {
      testbed.render({}, null, {disableLifecycleMethods: true})
      testbed.click(testbed.find('Button').at(1))
      expect(navigateBankEntryStub.called).to.eq(true)
    })

    it('clicking edit button should store focus as edit button', () => {
      testbed.render({}, null, {disableLifecycleMethods: true})
      testbed.click(testbed.find('Button').at(1))
      expect(setUiStub).to.be.calledWith(SET_EDIT_BUTTON_FOCUS, '1')
    })
  })
})
