<template>
  <view class="tn-countdown-class tn-countdown">
    <view
      v-if="showDays && (hideZeroDay || (!hideZeroDay && d != '00'))"
      class="tn-countdown__item"
      :class="[backgroundColorClass]"
      :style="[itemStyle]"
    >
      <view class="tn-countdown__item__time" :class="[fontColorClass]" :style="[letterStyle]">
        {{ d }}
      </view>
    </view>
    <view 
      v-if="showHours && (hideZeroDay || (!hideZeroDay && d != '00'))"
      class="tn-countdown__separator"
      :style="{
        fontSize: separatorSize + 'rpx',
        color: separatorColor,
        paddingBottom: separator === 'en' ? '4rpx' : 0
      }"
    >
      {{ separator === 'en' ? ':' : '天'}}
    </view>
    
    <view
      v-if="showHours"
      class="tn-countdown__item"
      :class="[backgroundColorClass]"
      :style="[itemStyle]"
    >
      <view class="tn-countdown__item__time" :class="[fontColorClass]" :style="[letterStyle]">
        {{ h }}
      </view>
    </view>
    <view 
      v-if="showMinutes"
      class="tn-countdown__separator"
      :style="{
        fontSize: separatorSize + 'rpx',
        color: separatorColor,
        paddingBottom: separator === 'en' ? '4rpx' : 0
      }"
    >
      {{ separator === 'en' ? ':' : '时'}}
    </view>
    
    <view
      v-if="showMinutes"
      class="tn-countdown__item"
      :class="[backgroundColorClass]"
      :style="[itemStyle]"
    >
      <view class="tn-countdown__item__time" :class="[fontColorClass]" :style="[letterStyle]">
        {{ m }}
      </view>
    </view>
    <view 
      v-if="showSeconds"
      class="tn-countdown__separator"
      :style="{
        fontSize: separatorSize + 'rpx',
        color: separatorColor,
        paddingBottom: separator === 'en' ? '4rpx' : 0
      }"
    >
      {{ separator === 'en' ? ':' : '分'}}
    </view>
    
    <view
      v-if="showSeconds"
      class="tn-countdown__item"
      :class="[backgroundColorClass]"
      :style="[itemStyle]"
    >
      <view class="tn-countdown__item__time" :class="[fontColorClass]" :style="[letterStyle]">
        {{ s }}
      </view>
    </view>
    <view 
      v-if="showSeconds && separator === 'cn'"
      class="tn-countdown__separator"
      :style="{
        fontSize: separatorSize + 'rpx',
        color: separatorColor,
        paddingBottom: separator === 'en' ? '4rpx' : 0
      }"
    >
      秒
    </view>
  </view>
</template>

<script>
  import componentsColorMixin from '../../libs/mixin/components_color.js'
  export default {
    name: 'tn-count-down',
    mixins: [componentsColorMixin],
    props: {
      // 倒计时时间，秒作为单位
      timestamp: {
        type: Number,
        default: 0
      },
      // 是否自动开始
      autoplay: {
        type: Boolean,
        default: true
      },
      // 数字框高度
      height: {
        type: [String, Number],
        default: 'auto'
      },
      // 分隔符类型
      // en -> 使用英文的冒号 cn -> 使用中文进行分割
      separator: {
        type: String,
        default: 'en'
      },
      // 分割符大小
      separatorSize: {
        type: Number,
        default: 30
      },
      // 分隔符颜色
      separatorColor: {
        type: String,
        default: '#080808'
      },
      // 是否显示边框
      showBorder: {
        type: Boolean,
        default: false
      },
      // 边框颜色
      borderColor: {
        type: String,
        default: '#080808'
      },
      // 是否显示秒
      showSeconds: {
        type: Boolean,
        default: true
      },
      // 是否显示分
      showMinutes: {
        type: Boolean,
        default: true
      },
      // 是否显示时
      showHours: {
        type: Boolean,
        default: true
      },
      // 是否显示天
      showDays: {
        type: Boolean,
        default: true
      },
      // 如果当天的部分为0时，是否隐藏不显示
      hideZeroDay: {
        type: Boolean,
        default: false
      }
    },
    computed: {
      // 倒计时item的样式
      itemStyle() {
        let style = {}
        if (this.height) {
          style.height = this.$tn.string.getLengthUnitValue(this.height)
          style.width = style.height
        }
        if (this.showBorder) {
          style.borderStyle = 'solid'
          style.borderColor = this.borderColor
          style.borderWidth = '1rpx'
        }
        style.backgroundColor = this.backgroundColorStyle || '#FFFFFF'
        return style
      },
      // 倒计时数字样式
      letterStyle() {
        let style = {}
        style.fontSize = this.fontSizeStyle || '30rpx'
        style.color = this.fontColorStyle || '#080808'
        return style
      }
    },
    data() {
      return {
        d: '00',
        h: '00',
        m: '00',
        s: '00',
        // 定时器
        timer: null,
        // 记录倒计过程中变化的秒数
        seconds: 0
      }
    },
    watch: {
      // 监听时间戳变化
      timestamp(value) {
        this.clearTimer()
        this.start()
      }
    },
    mounted() {
      // 如果时自动倒计时，加载完成开始计时
      this.autoplay && this.timestamp && this.start()
    },
    beforeDestroy() {
      this.clearTimer()
    },
    methods: {
      // 开始倒计时
      start() {
        // 避免可能出现的倒计时重叠情况
        this.clearTimer()
        if (this.timestamp <= 0) return
        this.seconds = Number(this.timestamp)
        this.formatTime(this.seconds)
        this.timer = setInterval(() => {
          this.seconds--
          // 发出change事件
          this.$emit('change', this.seconds)
          if (this.seconds < 0) {
            return this.end()
          }
          this.formatTime(this.seconds)
        }, 1000)
      },
      // 格式化时间
      formatTime(seconds) {
        // 小于等于0的话，结束倒计时
        seconds <= 0 && this.end()
        let [day, hour, minute, second] = [0, 0, 0, 0]
        day = Math.floor(seconds / (60 * 60 * 24))
        // 如果不显示天，则将天对应的小时计入到小时中
        // 先把当前的hour计算出来供分和秒使用
        hour = Math.floor(seconds / (60 * 60)) - (day * 24)
        let showHour = null
        if (this.showDays) {
          showHour = hour
        } else {
          // 将天数对应的小时加入到时中进行显示
          showHour = Math.floor(seconds / (60 * 60))
        }
        minute = Math.floor(seconds / 60) - (hour * 60) - (day * 24 * 60)
        second = Math.floor(seconds) - (minute * 60) - (hour * 60 * 60) - (day * 24 * 60 * 60)
        // 如果小于0在前面进行补0操作
        showHour = this.$tn.number.formatNumberAddZero(showHour)
        minute = this.$tn.number.formatNumberAddZero(minute)
        second = this.$tn.number.formatNumberAddZero(second)
        day = this.$tn.number.formatNumberAddZero(day)
        
        this.d = day
        this.h = showHour
        this.m = minute
        this.s = second
      },
      // 倒计时结束
      end() {
        this.clearTimer()
        this.$emit('end')
      },
      // 清除倒计时
      clearTimer() {
        if (this.timer !== null) {
          clearInterval(this.timer)
          this.timer = null
        }
      }
    }
  }
</script>

<style lang="scss" scoped>
  
  .tn-countdown {
    /* #ifndef APP-NVUE */
    display: inline-flex;
    /* #endif */
    align-items: center;
    
    &__item {
      box-sizing: content-box;
      display: flex;
      flex-direction: row;
      align-items: center;
      justify-content: center;
      padding: 2rpx;
      border-radius: 6rpx;
      white-space: nowrap;
      transform: translateZ(0);
      
      &__time {
        margin: 0;
        padding: 0;
        line-height: 1;
      }
    }
    
    &__separator {
      display: flex;
      flex-direction: row;
      align-items: center;
      justify-content: center;
      padding: 0 5rpx;
      line-height: 1;
    }
  }
</style>
