import ReactDOM from 'react-dom'
import ReactTestUtils from 'react-dom/test-utils'
import { List } from 'immutable'
import Menu from '@instructure/ui-menu/lib/components/Menu'
import Link from '@instructure/ui-elements/lib/components/Link'

import BankRecord from '../../../../common/records/Bank'
import BanksList from '../presenter'
import styles from '../styles.css'

import { withTestFeatures } from '../../../../common/util/featureCheck'

describe('BanksList', () => {
  const navigateToBankStub = sinon.stub()
  const openModalStub = sinon.stub()
  const withConfirmStub = sinon.stub()
  const deleteBankStub = sinon.stub()
  const focusCreateBankButtonStub = sinon.stub()
  const bank1 = new BankRecord({ id: '1', updatedAt: new Date('2017-03-14 14:01 UTC'), title: 'Algebraic', sharedCount: 2 })
  const bank2 = new BankRecord({ id: '999', updatedAt: Date.now(), title: 'Mathematical', sharedCount: 0})
  const banks = List([bank1, bank2])
  const testbed = createTestbed(withContext(BanksList), {
    banks,
    navigateToBank: navigateToBankStub
  })

  const shallowBanksListTestbed = createTestbed(BanksList, {
    banks,
    focusCreateBankButton: focusCreateBankButtonStub,
    deleteBank: deleteBankStub,
    navigateToBank: navigateToBankStub,
    openModal: openModalStub,
    withConfirm: withConfirmStub
  })

  afterEach(() => {
    deleteBankStub.resetHistory()
    focusCreateBankButtonStub.resetHistory()
    navigateToBankStub.resetHistory()
    openModalStub.resetHistory()
    withConfirmStub.resetHistory()
  })

  it('renders each bank', () => {
    testbed.render()
    const rows = testbed.findChildrenByClass(styles.bankInfo)
    expect(rows.length).to.eq(2)
    expect(testbed.getText(rows[0])).to.include('Algebraic')
    expect(testbed.getText(rows[0])).to.include('Updated Mar 14')
  })

  it('navigates to bank', () => {
    testbed.render()
    const rows = testbed.findChildrenBySelector(`.${styles.bankRow} button`)
    ReactTestUtils.Simulate.click(rows[2])
    expect(navigateToBankStub.calledWith('999')).to.be.true()
  })

  it('opens edit bank modal', () => {
    const shallowTestbed = shallowBanksListTestbed.renderShallowly()
    shallowTestbed.instance().openModal({id: '2'})()
    expect(openModalStub.calledWith('EDIT_BANK_MODAL:2')).to.be.true()
  })

  it('renders edit and delete options', () => {
    testbed.render()
    const menu = testbed.findChildrenByType(Menu)[0]
    expect(menu.props.children.length).to.equal(2)
  })

  describe('deleteBank', () => {
    it('opens a confirmation modal when deleting a bank', () => {
      const shallowTestbed = shallowBanksListTestbed.renderShallowly()
      shallowTestbed.instance().openDeleteBankModal('1')()
      expect(withConfirmStub).to.have.been.called()
    })

    it('calls delete bank', () => {
      const shallowTestbed = shallowBanksListTestbed.renderShallowly()
      shallowTestbed.instance().deleteBank('1')
      expect(deleteBankStub).to.have.been.calledWith('1')
    })

    it('focuses the create bank button', (done) => {
      const shallowTestbed = shallowBanksListTestbed.renderShallowly()
      shallowTestbed.instance().deleteBank('1')
      setTimeout(() => {
        expect(focusCreateBankButtonStub).to.have.been.called()
        done()
      }, 150)
    })
  })

  describe('sharing', () => {
    withTestFeatures(['item_bank_sharing'])

    it('should render the link to share', () => {
      testbed.render()
      expect(testbed.getText()).to.include('Share')
    })

    it('should open the modal when the link is clicked', () => {
      const subject = testbed.render()
      const shareLink = testbed.findChildrenByType(Link)[3]
      shareLink.props.onClick()
      expect(subject.refs.composedComponent.state.sharingModalOpen).to.be.true()
    })

    it('should close the modal when dismissed', () => {
      const subject = testbed.render()
      const comp = subject.refs.composedComponent
      comp.handleSharingModalDismiss()
      expect(subject.refs.composedComponent.state.sharingModalOpen).to.be.false()
    })

    it('should display +share when shareCount is 0', () => {
      testbed.render()
      const shareLink = testbed.findChildrenByType(Link)[3]
      const SharedLinkNode = ReactDOM.findDOMNode(shareLink)

      expect(SharedLinkNode.innerText).to.include('+ Share')
    })

    it('should display Sharing(shareCount) when shareCount > 0', () => {
      testbed.render()
      const shareLink = testbed.findChildrenByType(Link)[1]
      const SharedLinkNode = ReactDOM.findDOMNode(shareLink)

      expect(SharedLinkNode.innerText).to.include('Sharing (2)')
    })
  })

  it('should meet a11y standards', (done) => {
    testbed.render()
    testbed.checkA11yStandards(done, {
      ignores: [
        'aria-allowed-role' // TODO: remove this when instui fixes Select
      ]
    })
  })
})
