<template>
  <div class="mm-count-down">
    <ui-statistic v-bind="$attrs">
      <template #title>
        <slot name="title"></slot>
      </template>
      <template #prefix>
        <slot name="prefix"></slot>
      </template>
      <span class="mm-count-down-">
        {{ countDownText }}
      </span>
      <template #suffix>
        <slot name="suffix"></slot>
      </template>
    </ui-statistic>
  </div>
</template>

<script>

import { padStart, isEqual, isString } from "lodash"
import Statistic from "./../statistic"

const timeUnits = [
  ["Y", 1000 * 60 * 60 * 24 * 365], // years
  ["M", 1000 * 60 * 60 * 24 * 30], // months
  ["D", 1000 * 60 * 60 * 24], // days
  ["H", 1000 * 60 * 60], // hours
  ["m", 1000 * 60], // minutes
  ["s", 1000], // seconds
  ["S", 1], // million seconds
]

const REFRESH_INTERVAL = 1000 / 5

const valueReg = /[^\d\s\:]+/g

export default {
  name: "mm-count-down",
  components: {
    "ui-statistic": Statistic,
  },
  props: {
    value: {
      type: [Number, String, Date],
      default: "",
    },
    format: {
      type: String,
      default: "HH:mm:ss",
    },
  },
  data() {
    return {
      countDownId: null,
      countDownText: "",
    }
  },
  computed: {
    realValue() {
      if (isString(this.value)) {
        const replactText = this.value.replace(valueReg, "/")
        const replaceLen = replactText.length
        return replactText.slice(0, isEqual(replactText.lastIndexOf("/"), replaceLen)
          ? -1 : replaceLen)
      }
      return this.value
    },
  },
  created() {
    this.syncTimer()
  },
  methods: {
    formatTimeStr(leftDuration) {
      return timeUnits.reduce((currentText, [name, unit]) => {
        if (currentText.indexOf(name) !== -1) {
          const value = Math.floor(leftDuration / unit)
          leftDuration -= value * unit
          return currentText.replace(new RegExp(`${name}+`, "g"), match => {
            return padStart(value.toString(), match.length, "0")
          })
        }
        return currentText
      }, this.format)
    },
    syncTimer() {
      const getTime = new Date(this.realValue).getTime()
      const curTime = Date.now()
      this.countDownText = this.formatTimeStr(Math.max(getTime - curTime, 0))
      if (getTime > curTime) {
        this.startTimer()
      } else {
        this.stopTimer()
      }
    },
    startTimer() {
      if (this.countDownId) {
        clearInterval(this.countDownId)
      }
      this.countDownId = setInterval(() => {
        this.syncTimer()
      }, REFRESH_INTERVAL)
    },
    stopTimer() {
      if (this.countDownId) {
        clearInterval(this.countDownId)
        this.countDownId = null
      }
    },
  },
}
</script>
