import React from 'react'
import { Map } from 'immutable'

import { mount, find, findAll } from '@instructure/ui-test-utils'

import Modal from '@instructure/ui-overlays/lib/components/Modal'
import ItemFeedbackModal from '../presenter'

describe('ItemFeedbackModal', () => {
  const closeModalStub = sinon.stub()
  const openModalStub = sinon.stub()
  const changeItemFeedbackStub = sinon.stub()
  const setUiStub = sinon.stub()
  const modalProps = {
    changeItemFeedback: changeItemFeedbackStub,
    closeModal: closeModalStub,
    feedback: Map(),
    item: {id: 1, itemBody: 'itemStem'},
    modalOpen: true,
    openModal: openModalStub,
    setUi: setUiStub
  }
  const ConnectedItemFeedbackModal = withContext(ItemFeedbackModal)
  const testbed = createTestbed(ConnectedItemFeedbackModal, modalProps)
  const shallowtb = createTestbed(ItemFeedbackModal, modalProps)

  let shallowtestbed
  beforeEach(() => {
    shallowtestbed = shallowtb.renderShallowly()
  })

  afterEach(() => {
    closeModalStub.resetHistory()
    changeItemFeedbackStub.resetHistory()
    openModalStub.resetHistory()
    setUiStub.resetHistory()
  })

  shouldRenderComponent(testbed, {}, ItemFeedbackModal)

  describe('CreateItemFeedbackModal', () => {
    it('renders the modal', () => {
      const modal = shallowtestbed.find(Modal)
      expect(modal).to.have.length(1)
    })
  })

  describe('Modal Title', () => {
    it('renders the correct title for the modal', () => {
      const modalheader = shallowtestbed.find('ModalHeader')
      expect(modalheader).to.have.length(1)
      expect(modalheader.render().text()).to.be.equal('Student Feedback')
    })
  })

  describe('Item Stem', () => {
    it('renders the item stem in the modal', () => {
      testbed.render()
      expect(testbed.getText()).to.contain('itemStem')
    })
  })

  describe('Item Feedback Inputs', () => {
    it('sets feedback on change', () => {
      const subject = testbed.render()
      const event = { target: { id: 'correct' } }
      const component = subject.refs.composedComponent
      component.onFeedbackChange(event, { editorContent: 'some new content' })
      const newFeedback = setUiStub.firstCall.args[1]
      expect(newFeedback.get('correct')).to.equal('some new content')
    })
  })

  describe('Cancel action', () => {
    it('renders cancel button', () => {
      const cancelButton = shallowtestbed.find('Button[variant="default"]')
      expect(cancelButton.render().text()).to.include('Cancel')
    })

    it('calls the cancel action', () => {
      const cancelButton = shallowtestbed.find('Button[variant="default"]')
      cancelButton.simulate('click')
      expect(closeModalStub.called).to.be.true()
    })

    it('does not update feedback when the modal is cancelled', async () => {
      await mount(<ConnectedItemFeedbackModal {...modalProps} />)
      const cancelButton = await find(':label(Cancel)')
      const inputs = await findAll('textarea')
      const incorrectInput = inputs[1]
      await incorrectInput.change({ target: { id: 'incorrect', value: 'incorrect' } })
      await cancelButton.click()
      expect(changeItemFeedbackStub.called).to.be.false()
      expect(closeModalStub.called).to.be.true()
    })
  })

  describe('Done action', () => {
    it('renders the Done button', () => {
      const modalfooter = shallowtestbed.find('ModalFooter')
      const createButton = modalfooter.shallow({disableLifecycleMethods: true}).find('Button[variant="primary"]')
      expect(createButton.render().text()).to.include('Done')
    })

    it('updates item modifications when the modal is submitted', async () => {
      await mount(<ConnectedItemFeedbackModal {...modalProps} />)
      const doneButton = await find(':label(Done)')
      const inputs = await findAll('textarea')
      const incorrectInput = inputs[1]
      await incorrectInput.change({ target: { id: 'incorrect', value: 'incorrect' } })
      await doneButton.click()
      expect(changeItemFeedbackStub.called).to.be.true()
      expect(closeModalStub.called).to.be.true()
    })
  })
})
