import React, { Component, Fragment } from 'react'
import { number, func, bool } from 'prop-types'
import moment from 'moment'
import './CountDown.less'

const getDate = (date) => moment(date * (String(date).length > 10 ? 1 : 1000))

class CountDown extends Component {
  static propTypes = {
    date: number,
    showDate: bool,
    onFinish: func,
    getTranslation: func
  }

  state = {
    days: 0,
    hours: 0,
    min: 0,
    sec: 0,
    init: false,
    dateObject: null
  }

  componentDidMount() {
    const { date } = this.props
    this.setState({
      dateObject: getDate(date)
    }, this.initCountDown)
  }

  componentDidUpdate({ date: datePrev }, statePrev) {
    const { date } = this.props
    if (datePrev !== date) {
      this.setState({
        dateObject: getDate(date)
      }, this.tick)
    }
  }

  componentWillUnmount() {
    this.stop()
  }

  initCountDown () {
    this.tick()
    this.interval = setInterval(this.tick, 1000)
  }

  tick = () => {
    const data = this.calculateCountdown()
    data
      ? this.setState({
          ...data,
          init: true
        })
      : this.finish()
  }

  finish () {
    const { onFinish } = this.props
    if (onFinish) onFinish()
    this.stop()
  }

  calculateCountdown() {
    const { dateObject } = this.state
    let diff = dateObject.diff(moment(), 'seconds')
    // clear countdown when date is reached
    if (diff <= 0) return false

    const timeLeft = {
      years: 0,
      days: 0,
      hours: 0,
      min: 0,
      sec: 0
    }

    // calculate time difference between now and expected date
    if (diff >= (365.25 * 86400)) { // 365.25 * 24 * 60 * 60
      timeLeft.years = Math.floor(diff / (365.25 * 86400))
      diff -= timeLeft.years * 365.25 * 86400
    }
    if (diff >= 86400) { // 24 * 60 * 60
      timeLeft.days = Math.floor(diff / 86400)
      diff -= timeLeft.days * 86400
    }
    if (diff >= 3600) { // 60 * 60
      timeLeft.hours = Math.floor(diff / 3600)
      diff -= timeLeft.hours * 3600
    }
    if (diff >= 60) {
      timeLeft.min = Math.floor(diff / 60)
      diff -= timeLeft.min * 60
    }
    timeLeft.sec = diff

    return timeLeft
  }

  stop() {
    clearInterval(this.interval)
  }

  addLeadingZeros(value) {
    value = String(value)
    while (value.length < 2) {
      value = '0' + value
    }
    return value
  }

  getTranslation (key, counter) {
    if (counter === 1) return key.slice(0, -1)
    return key
  }

  render() {
    const { getTranslation = this.getTranslation, date, showDate } = this.props
    const { years, days, hours, min, sec, init } = this.state
    const startDate = moment.tz(date, moment.tz.guess()).format("dddd, MMMM Do YYYY [@] h:mmA z")
    const totalDays = days + (years * 365)

    if (!init) return null

    return (
      <Fragment>
        {showDate && <div className='demio-countdown-start-date'>{startDate}</div>}
        <div className='demio-countdown'>
          <div className="countdown-timer">
            <span key={totalDays} className='countdown-numbers'>
              {this.addLeadingZeros(totalDays)}</span> <span className='unit'>{getTranslation('days', totalDays)}
            </span>
          </div>
          <div className="countdown-timer">
            <span key={hours} className='countdown-numbers'>
              {this.addLeadingZeros(hours)}</span> <span className='unit'>{getTranslation('hours', hours)}
            </span>
          </div>
          <div className="countdown-timer">
            <span key={min} className='countdown-numbers'>
              {this.addLeadingZeros(min)}</span> <span className='unit'>{getTranslation('minutes', min)}
            </span>
          </div>
          <div className="countdown-timer">
            <span key={sec} className='countdown-numbers'>
              {this.addLeadingZeros(sec)}</span> <span className='unit'>{getTranslation('seconds', sec)}
            </span>
          </div>
        </div>
      </Fragment>
    )
  }
}

export default CountDown
