import React from 'react'
import ReactTestUtils from 'react-dom/test-utils'
import { fromJS } from 'immutable'
import OutcomeList from 'outcomes-react/lib/containers/OutcomeList'

import ItemAnalysis from '../../../../../common/records/ItemAnalysis'
import MetricsListItem from '../../../MetricsListItem'

// Components for render checks and interrogating the DOM
import ItemAnalysisRow from '../presenter'
import AnswerFrequencySummary from '../../AnswerFrequencySummary'

describe('ItemAnalysisRow', () => {
  const quizId = '1'
  const quizEntryId = '1'
  const getItemAnalysisStub = sinon.stub()
  const toggleExpandedStub = sinon.stub()
  const screenreaderNotificationStub = sinon.stub()

  const itemAnalysisData = {
    itemId: quizEntryId,
    itemBody: 'itemBody',
    position: 25,
    itemAnalysis: {
      scoreInfo: {
        resultSum: 5,
        resultCount: 1
      },
      difficultyInfo: {
        responseCount: 5,
        correctAnswerCount: 1
      },
      choiceInfo: [
        {
          choiceCount: 2,
          id: 'id',
          itemBody: 'choiceItemBody'
        }
      ],
      quintile: [1, 2, 3, 4, 5]
    }
  }

  const standardItemAnalysis = new ItemAnalysis(fromJS(itemAnalysisData))

  const testbed = createTestbed(withContext(ItemAnalysisRow), {
    expanded: false,
    getItemAnalysis: getItemAnalysisStub,
    itemAnalysis: standardItemAnalysis,
    itemId: quizEntryId,
    position: 25,
    quizId: quizId,
    toggleExpanded: toggleExpandedStub,
    screenreaderNotification: screenreaderNotificationStub
  })

  afterEach(() => {
    screenreaderNotificationStub.resetHistory()
  })

  shouldRenderComponent(testbed, {}, ItemAnalysisRow)

  it('should render the item analysis itemBody', () => {
    testbed.render()
    const output = testbed.getText()
    // Add more stuff here when we render an overview
    expect(output).to.include('itemBody')
  })

  it('should render the choice info', () => {
    testbed.render()
    const output = testbed.getText()
    expect(output).to.include('Difficulty Index')
    expect(output).to.include('Discrimination Index')
    expect(output).to.include('RPB')
    expect(output).to.include('Mean Earned Score')
  })

  it('should render only the metrics supplied as children', () => {
    testbed.render({
      children: [
        <MetricsListItem
          label={'Difficulty Index'}
          value={5}
          key={'DifficultyIndex'} />
      ]
    })

    const output = testbed.getText()
    expect(output).to.include('Difficulty Index')
    expect(output).to.not.include('Discrimination Index')
    expect(output).to.not.include('RPB')
    expect(output).to.not.include('Mean Earned Score')
  })

  it('should render empty text when not found', () => {
    const notFoundItemAnalysis = new ItemAnalysis(fromJS({
      itemId: quizEntryId,
      notFound: true
    }))
    testbed.render({itemAnalysis: notFoundItemAnalysis})
    const output = testbed.getText()
    expect(output).to.include('No submissions yet')
    expect(output).to.not.include('Discrimination Index')
    expect(testbed.findChildrenByTagName('button').length).to.eq(0)
  })

  describe('expandable', () => {
    shouldRenderComponent(testbed, { expanded: true }, AnswerFrequencySummary)

    it('should read correctly', () => {
      testbed.render()
      expect(testbed.getText()).to.include('Expand item 25')
      expect(testbed.getText()).to.not.include('Collapse item 25')
      testbed.render({expanded: true})
      expect(testbed.getText()).to.include('Collapse item 25')
      expect(testbed.getText()).to.not.include('Expand item 25')
    })

    it('clicking down arrow should trigger expand toggle', () => {
      testbed.render()
      const icon = testbed.findChildrenByTagName('button')[0]
      ReactTestUtils.Simulate.click(icon)
      expect(toggleExpandedStub).to.be.calledOnce()
      expect(screenreaderNotificationStub).to.be.calledOnce()
    })

    it('should render the expanded answer info', () => {
      testbed.render({expanded: true})
      const output = testbed.getText()
      expect(output).to.include('choiceItemBody')
      expect(output).to.include('Respondents')
    })

    it('should render the expanded answer info', () => {
      const newItemAnalysisData = {...itemAnalysisData}
      newItemAnalysisData.itemAnalysis.choiceInfo = []
      const newItemAnalysis = new ItemAnalysis(fromJS(itemAnalysisData))
      testbed.render({itemAnalysis: newItemAnalysis, expanded: true})
      const output = testbed.getText()
      expect(output).to.not.include('choiceItemBody')
      expect(output).to.not.include('Respondents')
    })
  })

  describe('outcome alignments', () => {
    const outcomesEndpoint = 'http://outcomes'
    const outcomesToken = 'token'
    const outcomesItemAnalysis = new ItemAnalysis(fromJS({
      ...itemAnalysisData,
      outcomeAlignmentSetGuid: 'foo'
    }))

    const outcomesParams = {
      expanded: true,
      outcomesEndpoint,
      outcomesToken,
      itemAnalysis: outcomesItemAnalysis
    }

    it('should render alignments if expanded, configured, and guid present', () => {
      testbed.render(outcomesParams)
      expect(testbed.findChildrenByType(OutcomeList)).to.have.length(1)
    })

    it('should not render alignments if not expanded', () => {
      testbed.render({
        ...outcomesParams,
        expanded: false
      })
      expect(testbed.findChildrenByType(OutcomeList)).to.have.length(0)
    })

    it('should not render alignments if outcomes host not configured', () => {
      testbed.render({
        ...outcomesParams,
        outcomesEndpoint: null
      })
      expect(testbed.findChildrenByType(OutcomeList)).to.have.length(0)
    })

    it('should not render alignments if outcomes guid not present', () => {
      testbed.render({
        ...outcomesParams,
        itemAnalysis: standardItemAnalysis
      })
      expect(testbed.findChildrenByType(OutcomeList)).to.have.length(0)
    })
  })
})
