import { findDOMNode } from 'react-dom'
import ScreenReaderContent from '@instructure/ui-a11y/lib/components/ScreenReaderContent'

import Distribution, {starPathData} from '../presenter'
import styles from '../styles.css'

describe('Distribution', () => {
  const testbed = createTestbed(Distribution, {
    animateDelay: null,
    animateDuration: null,
    chartHeight: 120,
    chartWidth: 200,
    visualDistribution: [0, 1, 2, 3]
  })

  const getBars = function () {
    return testbed.findChildrenBySelector(`.${styles.barContainer} rect`)
  }

  shouldRenderComponent(testbed, {}, Distribution)

  it('does not render a star by default', () => {
    testbed.render()
    const bars = testbed.findChildrenByClass(styles.barStar)
    expect(bars).to.have.length(0)
  })

  it('should render bars with relative height', () => {
    testbed.render()

    const bars = getBars()
    expect(bars.map((b) => { return b.attributes.y.value })).to.eql(['120', '80', '40', '0'])
    expect(bars.map((b) => { return b.attributes.height.value })).to.eql(['0', '40', '80', '120'])
  })

  it('should determine number of bands from distribution', () => {
    testbed.render({ barPaddingInner: 0 })

    const bars = getBars()
    expect(bars.length).to.eq(4)
    bars.forEach((b) => { expect(b.attributes.width.value).to.eq('50') })
  })

  context('with star index', () => {
    it('styles starred bar', () => {
      testbed.render({ starIndex: 1 })
      const bars = testbed.findChildrenBySelector(`.${styles.barContainer} rect`)
      expect(bars.findIndex(b => b.className.baseVal.includes(styles.barStar))).to.eq(1)
    })

    it('renders the star', () => {
      testbed.render({ starIndex: 1 })
      const stars = testbed.findChildrenBySelector(`path[d="${starPathData}"`)
      expect(stars).to.have.length(1)
    })
  })

  describe('summary', () => {
    const srText = () => {
      const srNode = findDOMNode(testbed.findChildByType(ScreenReaderContent))
      return testbed.getText(srNode)
    }

    it('should render', () => {
      testbed.render()

      const text = srText()
      expect(text).to.include(' 1 student scored between 25% and 50%.')
      expect(text).to.include(' 2 students scored between 50% and 75%.')
      expect(text).to.match(/ 3 students scored between 75% and 100%\.$/)
    })

    it('should not render for nonexistent distribution data', () => {
      testbed.render({ summaryDistribution: [] })
      expect(srText()).to.eq('')
    })

    it('should not render for empty distribution data', () => {
      testbed.render({ summaryDistribution: [0, 0, 0] })
      expect(srText()).to.eq('')
    })

    it('should not render for insufficient distribution data', () => {
      testbed.render({ summaryDistribution: [100] })
      expect(srText()).to.eq('')
    })

    it('should calculate average', () => {
      testbed.render({ summaryDistribution: [2, 1, 2] })
      expect(srText()).to.match(/^3 students scored above or at the average, and 2 below\./)
    })

    it('should calculate average for low scores', () => {
      testbed.render({ summaryDistribution: [3, 0, 0] })
      expect(srText()).to.match(/^3 students scored above or at the average, and 0 below\./)
    })

    it('should calculate average for high scores', () => {
      testbed.render({ summaryDistribution: [0, 0, 3] })
      expect(srText()).to.match(/^3 students scored above or at the average, and 0 below\./)
    })
  })
})
