<template>
  <div class="lottery-entry">
    <div v-if="!isLoading" ref="lotteryEntryIcon" class="lottery-entry__icon">
      <span
        class="lottery-entry__status"
        :class="`lottery-entry__status--${SESSION_STATUS_TXT[sessionStatus].className}`"
      >
        {{ sessionStatus === SESSION_STATUS.drawing ? '开奖中' : SESSION_STATUS_TXT[sessionStatus].label }}
      </span>
    </div>
    <div v-show="isInitialized" ref="lotteryEntryContent" class="lottery-entry__main">
      <div class="lottery-entry__content">
        <div class="lottery-entry__info">
          <div class="lottery-entry__info-top">
            <div v-if="sessionStatus !== SESSION_STATUS.drawing" class="lottery-entry__type">
              {{ LOTTERY_TYPE_TXT[lotteryType] }}
            </div>
            <div class="lottery-entry__status-text">
              <template v-if="sessionStatus === SESSION_STATUS.drawing">
                {{ SESSION_STATUS_TXT[sessionStatus].label }}
              </template>
              <template v-else>
                {{ JOIN_STATUS_TXT[isDraw] }}
              </template>
            </div>
          </div>
          <div class="lottery-entry__info-bottom">
            <div class="lottery-entry__draw-info">
              <template v-if="isShowCountDown">
                还剩
                <span>{{ timeText }}</span>
                {{ joinText[sessionStatus] }}
              </template>
              <!-- 活动已开始 & 待开奖 + 人数条件 + 留言抽奖 -->
              <template
                v-if="
                  lotteryType === LOTTERY_TYPE.message &&
                  sessionStatus === SESSION_STATUS.start &&
                  sessionCondition === LOTTERY_MESSAGE_RULES.people
                "
              >
                还剩<span>{{ surplusJoin }}位</span>停止参与
              </template>
              <!-- 活动已结束 & 已开奖 -->
              <template v-if="sessionStatus === SESSION_STATUS.end">
                <p @click.self.stop="openResult">查看中奖纪录</p>
              </template>
            </div>
          </div>
        </div>
        <div
          v-if="sessionStatus === SESSION_STATUS.start && isDraw === JOIN_STATUS.no"
          class="lottery-entry__operate"
          @click.self="onJoinHandler"
        >
          立即参与
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import {
  LOTTERY_TYPE,
  LOTTERY_TYPE_TXT,
  LOTTERY_STATUS,
  SESSION_STATUS,
  SESSION_STATUS_TXT,
  LOTTERY_MESSAGE_RULES,
  JOIN_STATUS,
  JOIN_STATUS_TXT
} from '@/utils/constant'
// import { getLiveLottery } from '@/api/modules/lottery'
import tippy from 'tippy.js'
import 'tippy.js/dist/tippy.css'
import 'tippy.js/animations/shift-away.css'

export default {
  name: 'Index',
  props: {
    theme: {
      type: String,
      default: 'dark' // light | dark
    },
    liveId: {
      type: [String, Number],
      default: null
    },
    userId: {
      type: [String, Number],
      default: null
    },
    includeType: {
      type: String,
      default: 'live'
    },
    zIndex: {
      type: Number,
      default: 1000
    },
    autoClose: {
      type: Boolean,
      default: true
    },
    autoCloseDuration: {
      type: Number,
      default: 15000
    },
    retrieveApi: {
      type: Function,
      default: null // getLiveLottery
    }
  },
  data() {
    return {
      LOTTERY_TYPE,
      LOTTERY_TYPE_TXT,
      SESSION_STATUS,
      SESSION_STATUS_TXT,
      LOTTERY_MESSAGE_RULES,
      JOIN_STATUS,
      JOIN_STATUS_TXT,
      lotteryInfo: this.lotteryInfoTranslator(),
      isInitialized: false,
      isLoading: true,
      timer: null,
      closeTimer: null,
      timeText: '',
      joinText: {
        [SESSION_STATUS.teaser]: '活动开始',
        [SESSION_STATUS.start]: '停止参与'
      },
      popInstance: null
    }
  },
  computed: {
    lotteryType() {
      // 默认为消息抽奖
      return this.lotteryInfo.type
    },
    lotteryStatus() {
      return this.lotteryInfo.status
    },
    sessionCondition() {
      // 默认为时间
      return this.lotteryInfo.playConfig.condition
    },
    sessionStatus() {
      // 默认为未开始
      return this.lotteryInfo.playConfig.status
    },
    isDraw() {
      // 默认为已参与
      return this.lotteryInfo.playConfig.isDraw
    },
    sessionStartTime() {
      return this.lotteryInfo.playConfig.startTime
    },
    sessionEndTime() {
      return this.lotteryInfo.playConfig.endTime
    },
    surplusJoin() {
      // 剩余参与人数
      const { joinNum: sum, activeNum } = this.lotteryInfo.playConfig
      const surplus = sum - activeNum
      return surplus < 0 ? 0 : surplus
    },
    isShowCountDown() {
      const { sessionStatus, lotteryType, sessionCondition } = this
      // 活动未开始
      if (sessionStatus === SESSION_STATUS.teaser) {
        return true
      }
      //  活动已开始(待开奖) + 时间条件 + 留言抽奖 || 非留言抽奖 + 活动已开始
      const otherRules = lotteryType === LOTTERY_TYPE.message ? sessionCondition === LOTTERY_MESSAGE_RULES.time : true
      if (sessionStatus === SESSION_STATUS.start && otherRules) {
        return true
      }
      return false
    }
  },
  mounted() {
    if (this.liveId && this.includeType && this.retrieveApi) {
      this.loadData()
    } else {
      // eslint-disable-next-line no-console
      console.error('组件参数缺少')
    }
  },
  methods: {
    popoverInit() {
      this.$nextTick(() => {
        const self = this
        const triggerDom = this.$refs?.lotteryEntryIcon
        const contentDom = this.$refs?.lotteryEntryContent
        this.popInstance = tippy(triggerDom, {
          trigger: 'click',
          interactive: true,
          placement: 'left',
          appendTo: document.body,
          content: contentDom,
          zIndex: this.zIndex,
          theme: this.theme,
          animation: 'shift-away',
          onCreate() {
            self.isInitialized = true
          },
          onShow(instance) {
            if (self.autoClose) {
              self.closeTimer = setTimeout(() => {
                instance.popper.firstElementChild.classList.remove('tippy--open')
                requestAnimationFrame(() => {
                  instance.hide()
                })
              }, self.autoCloseDuration)
            }
          },
          onHide(instance) {
            self.closeTimer && clearInterval(self.closeTimer)
            instance.popper.firstElementChild.classList.remove('tippy--open')
          },
          onShown(instance) {
            requestAnimationFrame(() => {
              instance.popper.firstElementChild.classList.add('tippy--open')
            })
          }
          // onHidden(instance) {
          //   if (!self.autoClose) {
          //     instance.popper.firstElementChild.classList.remove('tippy--open')
          //   }
          // }
        })
      })
    },
    showPopover() {
      if (this.popInstance?.show) {
        this.popInstance.show()
      }
    },
    hidePopover() {
      if (this.popInstance?.hide) {
        this.popInstance.hide()
      }
    },
    popoverUpdate() {
      if (this.popInstance?.popperInstance?.update) {
        this.popInstance.popperInstance.update()
      }
    },
    loadData() {
      const { liveId: channelId, includeType, retrieveApi } = this
      this.isLoading = true
      retrieveApi({ channelId, type: includeType })
        .then(res => {
          const { code, errorCode, data } = res
          if (code === 200 && errorCode === 0) {
            this.lotteryInfo = this.lotteryInfoTranslator(data)
            this.isLoading = false
            this.runCountDown()
          } else {
            this.isLoading = false
          }
          this.popoverInit()
        })
        .catch(() => {
          this.isLoading = false
        })
    },
    // 打开中奖结果
    openResult() {
      this.$emit('openResult', this.lotteryInfo)
    },
    // 参与的动作
    onJoinHandler() {
      this.$emit('onJoin', this.lotteryInfo)
    },
    runCountDown() {
      this.timer && clearInterval(this.timer)
      const { sessionStatus, sessionStartTime, sessionEndTime } = this
      const now = new Date().getTime()
      let endTime = 0
      if (sessionStatus === SESSION_STATUS.teaser) {
        endTime = sessionStartTime * 1000
      }
      if (sessionStatus === SESSION_STATUS.start) {
        endTime = sessionEndTime * 1000
      }
      let diff = parseInt(endTime - now, 10) / 1000
      this.timer = setInterval(() => {
        if (diff <= 0) {
          clearInterval(this.timer)
          return
        }
        diff -= 1
        this.timeText = this.formatDiffTime(diff)
      }, 1000)
    },
    formatClockNum(i) {
      return i < 10 ? `0${i}` : i
    },
    formatDiffTime(diff) {
      const { formatClockNum } = this
      const d = parseInt(diff / (24 * 60 * 60), 10)
      const h = parseInt((diff / (60 * 60)) % 24, 10)
      const m = parseInt((diff / 60) % 60, 10)
      const s = parseInt(diff % 60, 10)

      if (d > 0) {
        return `${formatClockNum(d)}天`
      }
      if (h > 0) {
        return `${formatClockNum(h)}小时`
      }
      if (m >= 0 && s >= 0) {
        return `${formatClockNum(m)}:${formatClockNum(s)}`
      }
      return ''
    },
    // 处理dms消息 数据更新
    dmsListener(data) {
      const { lotteryInfo, userId } = this
      switch (data.cmd) {
        // 参与成功
        case 'draw_join_success':
          if (+data.id === lotteryInfo.id && +data.playId === lotteryInfo.playConfig.id) {
            // 更新参与人数
            this.$set(this.lotteryInfo, 'playConfig', {
              ...lotteryInfo.playConfig,
              activeNum: lotteryInfo.playConfig.activeNum + 1
            })
            if (+data.userId === +userId) {
              // 更新用户是否参与
              this.$set(this.lotteryInfo, 'playConfig', { ...lotteryInfo.playConfig, isDraw: 1 })
            }
          }
          break
        case 'draw_service':
          if (+data.id === lotteryInfo.id) {
            // 更新场次信息
            if ('nextPlayConfig' in data) {
              this.$set(this.lotteryInfo, 'playConfig', { ...lotteryInfo.playConfig, ...data.nextPlayConfig })
            }
            // 更新符合当前场次的状态
            if (+data.playId === lotteryInfo.playConfig.id) {
              this.$set(this.lotteryInfo, 'playConfig', { ...lotteryInfo.playConfig, status: +data.status })
            }
            // 重新运行倒计时
            this.runCountDown()
          }
          break
        case 'draw_bind':
          // 1绑定 0解绑
          if (+data.status === 1) {
            this.lotteryInfo = this.lotteryInfoTranslator(data.drawInfo)
            this.runCountDown()
          }
          break
        default:
          break
      }
    },
    lotteryInfoTranslator(data) {
      const playConfig = data?.playConfig || {}
      return {
        ...data,
        id: data?.id || '',
        type: +data?.type || LOTTERY_TYPE.message,
        status: +data?.status || LOTTERY_STATUS.teaser,
        playConfig: {
          ...playConfig,
          id: +playConfig?.id || '',
          status: +playConfig?.status || SESSION_STATUS.teaser,
          condition: +playConfig?.condition || LOTTERY_MESSAGE_RULES.time,
          isDraw: +playConfig?.isDraw || JOIN_STATUS.no,
          startTime: playConfig?.startTime || 0,
          endTime: playConfig?.endTime || 0,
          joinNum: +playConfig?.joinNum || 0,
          activeNum: +playConfig?.activeNum || 0
        }
      }
    }
  }
}
</script>

<style lang="less">
@--baseSize: 12em; // 1px

/* tippy animation */
@keyframes pulsating {
  0%,
  72% {
    transform: translateX(0px);
  }
  79% {
    transform: translateX(5 / @--baseSize);
  }
  86% {
    transform: translateX(0px);
  }
  93% {
    transform: translateX(5 / @--baseSize);
  }
  100% {
    transform: translateX(0px);
  }
}
.tippy {
  &--open {
    animation: pulsating 6s infinite linear;
    animation-delay: 0.5s;
  }
}
/* tippy reset */
.tippy-content {
  padding: 0;
}
/* tippy theme */
.tippy-box[data-theme~='light'] {
  background-color: rgba(255, 255, 255, 0.89);
  .tippy-arrow {
    color: rgba(255, 255, 255, 0.89);
  }
  &.tippy-box[data-placement^='left'] {
    .tippy-arrow:before {
      right: -7 / @--baseSize;
    }
  }
  .lottery-entry__info {
    color: #333;
  }
  .lottery-entry__status-text {
    color: #fa6400;
  }
  .lottery-entry__operate {
    color: #578df0;
    border-left: 1 / @--baseSize solid #cfcfcf;
  }
}
.tippy-box[data-theme~='dark'] {
  background-color: rgba(67, 67, 67, 0.87);
  .tippy-arrow {
    color: rgba(67, 67, 67, 0.87);
  }
  &.tippy-box[data-placement^='left'] {
    .tippy-arrow:before {
      right: -7 / @--baseSize;
    }
  }
  .lottery-entry__info {
    color: #fff;
  }
  .lottery-entry__status-text {
    color: #fa6400;
  }
  .lottery-entry__operate {
    color: #fff798;
    border-left: 1 / @--baseSize solid #656565;
  }
}
</style>
<style lang="less" scoped>
@--baseSize: 12em; // 1px
.lottery-entry {
  font-size: 12px;
  display: flex;
  justify-content: flex-end;
  &__icon {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: flex-end;
    width: 48 / @--baseSize;
    height: 48 / @--baseSize;
    background-image: url(https://guangdianyun.oss-cn-hangzhou.aliyuncs.com/common/img/lottery_entry_icon.png);
    background-repeat: no-repeat;
    background-size: cover;
    background-position: center;
  }
  &__status {
    transform: translateY(4 / @--baseSize) scale(0.8);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 4 / @--baseSize;
    height: 16 / @--baseSize;
    line-height: 16 / @--baseSize;
    font-size: 12 / @--baseSize;
    background-color: #fff;
    border-radius: 10 / @--baseSize;
    &--teaser {
      color: #f90;
    }
    &--start {
      color: #0091ff;
    }
    &--end {
      color: #999;
    }
  }
  &__main {
    font-size: 12px;
  }
  &__content {
    transform: translateX(0);
    border-radius: 6 / @--baseSize;
    padding: 5 / @--baseSize;
    font-size: 12 / @--baseSize;
    display: flex;
    min-width: 100 / @--baseSize;
  }
  &__info {
    flex: 1;
    white-space: nowrap;
    display: flex;
    flex-direction: column;
    padding-right: 4 / @--baseSize;
  }
  &__info-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  &__type {
    font-size: 12 / @--baseSize;
    display: flex;
    align-items: center;
    height: 14 / @--baseSize;
    line-height: 14 / @--baseSize;
  }
  &__status-text {
    font-size: 12 / @--baseSize;
    display: flex;
    align-items: center;
    height: 14 / @--baseSize;
    line-height: 14 / @--baseSize;
  }
  &__info-bottom {
    margin-top: 2 / @--baseSize;
  }
  &__draw-info {
    span {
      color: #578df0;
      margin: 0 4 / @--baseSize;
    }
    p {
      min-width: 90 / @--baseSize;
      text-align: center;
    }
  }
  &__operate {
    width: 30 / @--baseSize;
    color: #578df0;
    font-weight: 500;
    padding-left: 4 / @--baseSize;
    border-left: 1 / @--baseSize solid #cfcfcf;
    font-size: 12 / @--baseSize;
    display: flex;
    align-items: center;
  }
}
</style>
