import FormattedDuration, { getHoursMinutesSeconds, pad } from '../index'
import createTestbed from '../../../../../../tests/util/react-testbed'

import styles from '../styles.css'

describe('FormattedDuration Presenter', () => {
  const props = {
    timeLimitInSeconds: 3600,
    styles: {hours: {}, minutes: {}, seconds: {}}
  }

  const testbed = createTestbed(FormattedDuration, props)

  const TEN_SECONDS = 10
  const SEVEN_SECONDS = 7
  const FIFTY_NINE_SECONDS = 59
  const FIVE_MINUTES = 60 * 5
  const SEVEN_MINUTES = 60 * 7
  const TWO_HOURS = 60 * 60 * 2

  describe('#getHoursMinutesSeconds', () => {
    context('with time limit in hours', () => {
      it('outputs a hash with correct hours', () => {
        const output = getHoursMinutesSeconds(TWO_HOURS)
        expect(output.hours).to.eq(2)
      })

      context('with minutes', () => {
        it('outputs a hash with correct hours and minutes', () => {
          const output = getHoursMinutesSeconds(TWO_HOURS + FIVE_MINUTES)
          expect(output.hours).to.eq(2)
          expect(output.minutes).to.eq(5)
        })

        context('with seconds', () => {
          it('outputs a hash with correct hours and minutes and seconds', () => {
            const output = getHoursMinutesSeconds(TWO_HOURS + FIVE_MINUTES + TEN_SECONDS)
            expect(output.hours).to.eq(2)
            expect(output.minutes).to.eq(5)
            expect(output.seconds).to.eq(10)
          })
        })
      })
    })

    context('with time limit in minutes', () => {
      it('outputs a hash with hours to 0', () => {
        const output = getHoursMinutesSeconds(FIVE_MINUTES)
        expect(output.hours).to.eq(0)
      })

      it('outputs a hash with correct minutes', () => {
        const output = getHoursMinutesSeconds(SEVEN_MINUTES)
        expect(output.minutes).to.eq(7)
      })

      context('with seconds', () => {
        it('outputs a hash with correct minutes and seconds', () => {
          const output = getHoursMinutesSeconds(SEVEN_MINUTES + FIFTY_NINE_SECONDS)
          expect(output.minutes).to.eq(7)
          expect(output.seconds).to.eq(59)
        })
      })
    })

    context('with time limit in seconds', () => {
      it('outputs a hash with hours to 0', () => {
        const output = getHoursMinutesSeconds(FIFTY_NINE_SECONDS)
        expect(output.hours).to.eq(0)
      })

      it('outputs a hash with minutes to 0', () => {
        const output = getHoursMinutesSeconds(FIFTY_NINE_SECONDS)
        expect(output.minutes).to.eq(0)
      })

      it('outputs a hash with seconds set correctly', () => {
        const output = getHoursMinutesSeconds(SEVEN_SECONDS + TEN_SECONDS)
        expect(output.seconds).to.eq(17)
      })
    })

    context('with 0 passed in', () => {
      it('outputs a hash with hours, minutes, and seconds set to 0', () => {
        const output = getHoursMinutesSeconds(0)
        expect(output.hours).to.eq(0)
        expect(output.minutes).to.eq(0)
        expect(output.seconds).to.eq(0)
      })
    })

    context('with null passed in', () => {
      it('outputs a hash with hours, minutes, and seconds set to 0', () => {
        const output = getHoursMinutesSeconds(null)
        expect(output.hours).to.eq(0)
        expect(output.minutes).to.eq(0)
        expect(output.seconds).to.eq(0)
      })
    })

    context('with undefined passed in', () => {
      it('outputs a hash with hours, minutes, and seconds set to 0', () => {
        const output = getHoursMinutesSeconds(void 0)
        expect(output.hours).to.eq(0)
        expect(output.minutes).to.eq(0)
        expect(output.seconds).to.eq(0)
      })
    })
  })

  describe('#pad', () => {
    it('adds a 0 if number is less than 10', () => {
      expect(pad(7)).to.eq('07')
    })

    it('doesn\'t add a 0 if number is more than 10', () => {
      expect(pad(17)).to.eq('17')
    })
  })

  describe('#render', () => {
    context('with hours', () => {
      it('displays the hours, minutes, and seconds', () => {
        testbed.render({timeLimitInSeconds: TWO_HOURS + FIVE_MINUTES + TEN_SECONDS})
        const text = testbed.getText()
        expect(text).to.include('02')
        expect(text).to.include('05')
        expect(text).to.include('10')
      })
    })

    context('with no hours', () => {
      it('does display the minutes and seconds', () => {
        testbed.render({timeLimitInSeconds: FIVE_MINUTES + TEN_SECONDS})
        const text = testbed.getText()
        expect(text).to.include('05')
        expect(text).to.include('10')
      })
    })

    context('with minutes', () => {
      it('displays the minutes and seconds', () => {
        testbed.render({timeLimitInSeconds: FIVE_MINUTES + TEN_SECONDS})
        const text = testbed.getText()
        expect(text).to.include('05')
        expect(text).to.include('10')
      })

      it('styles the minutes and seconds with the dark style', () => {
        testbed.render({timeLimitInSeconds: FIVE_MINUTES + TEN_SECONDS})
        const count = testbed.findChildrenByClass(styles.dark).length
        expect(count).to.eq(2)
      })
    })

    context('with no minutes', () => {
      it('displays the minutes and seconds', () => {
        testbed.render({timeLimitInSeconds: TEN_SECONDS})
        const text = testbed.getText()
        expect(text).to.include('00')
        expect(text).to.include('10')
      })

      it('does not style the minutes with the dark style', () => {
        testbed.render({timeLimitInSeconds: TEN_SECONDS})
        const count = testbed.findChildrenByClass(styles.dark).length
        expect(count).to.eq(1)
      })
    })

    context('with no time', () => {
      it('displays the minutes and seconds', () => {
        testbed.render({timeLimitInSeconds: 0})
        const text = testbed.getText()
        expect(text).to.include('00')
        expect(text).to.not.include('10')
      })

      it('does not style the minutes or seconds with the dark style', () => {
        testbed.render({timeLimitInSeconds: 0})
        const count = testbed.findChildrenByClass(styles.dark).length
        expect(count).to.eq(0)
      })
    })
  })

  describe('a11y tests', () => {
    it('should meet a11y standards', (done) => {
      testbed.render()
      testbed.checkA11yStandards(done)
    })
  })
})
