import React from 'react'
import { accessible, expect, mount, stub, waitForExpect } from '@instructure/ui-test-utils'
import ModalLocator from '@instructure/ui-overlays/lib/components/Modal/locator'

import ConfirmationModal from '../presenter'

describe('Confirmation Modal', () => {
  const render = async ({ closeModal = Function.prototype, modalOpen = true, ...options } = {}) => {
    return await mount(
      <ConfirmationModal
        closeModal={ closeModal }
        modalOpen={ modalOpen }
        {...options}
      />
    )
  }

  describe('modal header', () => {
    it('renders the given title as a label', async () => {
      const customTitle = 'Remove Item?'
      await render({ title: customTitle })
      expect(await ModalLocator.find(`:label('${customTitle}')`)).to.exist()
    })

    it('renders the given title', async () => {
      const customTitle = 'What Item?'
      await render({ title: customTitle })
      const modal = await ModalLocator.find()
      const header = await modal.findHeader()
      expect(header.text()).to.include(customTitle)
    })

    it('renders a default title if none given', async () => {
      const standardTitle = 'Confirm'
      await render()
      const modal = await ModalLocator.find()
      const header = await modal.findHeader()
      expect(header.text()).to.include(standardTitle)
    })

    it('renders a close button', async () => {
      await render()
      const modal = await ModalLocator.find()
      const header = await modal.findHeader()
      const closeButton = await header.find('button')
      expect(closeButton).to.have.text('Close')
    })
  })

  describe('modal footer', () => {
    it('renders the cancelText if given', async () => {
      const customText = 'Dont do it'
      await render({ cancelText: customText })
      const modal = await ModalLocator.find()
      const footer = await modal.findFooter()
      const cancelButton = (await footer.findAll('button'))[0]
      expect(cancelButton).to.have.text('Dont do it')
    })

    it('renders the continueText if given', async () => {
      const customText = 'Do it'
      await render({ continueText: customText })
      const modal = await ModalLocator.find()
      const footer = await modal.findFooter()
      const continueButton = (await footer.findAll('button'))[1]
      expect(continueButton).to.have.text('Do it')
    })
  })

  describe('main content', () => {
    it('renders the text given', async () => {
      const customText = 'Are you sure you wan\'t to do this?'
      await render({ text: customText })
      const modal = await ModalLocator.find()
      const body = await modal.findBody()
      expect(body).to.have.text(customText)
    })
  })

  describe('actions', () => {
    const findButtonWithText = async (text) => {
      const modal = await ModalLocator.find()
      const footer = await modal.findFooter()
      const button = await footer.find(`button:contains(${text})`)
      return button
    }

    it('calls cancelCb when you hit cancel', async () => {
      const cancelCbStub = stub()
      const subject = await render({ onCancel: cancelCbStub })
      const cancelButton = await findButtonWithText('Cancel')
      await cancelButton.click()
      await subject.setProps({ modalOpen: false })
      await waitForExpect(() => expect(cancelCbStub).to.have.been.called())
    })

    it('calls continueCb when you hit continue', async () => {
      const continueCbStub = stub()
      const subject = await render({ onContinue: continueCbStub })
      const confirmButton = await findButtonWithText('Confirm')
      await confirmButton.click()
      await subject.setProps({ modalOpen: false })
      await waitForExpect(() => expect(continueCbStub).to.have.been.called())
    })

    it('calls closeModal when you hit cancel', async () => {
      const closeModalStub = stub()
      await render({ closeModal: closeModalStub })
      const cancelButton = await findButtonWithText('Cancel')
      await cancelButton.click()
      await waitForExpect(() => expect(closeModalStub).to.have.been.called())
    })

    it('calls closeModal when you hit continue', async () => {
      const closeModalStub = stub()
      await render({ closeModal: closeModalStub })
      const confirmButton = await findButtonWithText('Confirm')
      await confirmButton.click()
      await waitForExpect(() => expect(closeModalStub).to.have.been.called())
    })
  })

  describe('a11y tests', () => {
    it('is accessible', async () => {
      await render()
      expect(await accessible()).to.be.true()
    })
  })
})
