<template>
  <div class="player" v-if="chatperResources">
    <div class="player-main">
      <div class="player-column" v-show="videoVisible">
        <!-- 视频 -->
        <video-player
          :isSkip="isSkip"
          :skipTime="skipTime"
          :video="chatperResources.video"
          @timeupdate="onTimeupdate"
          @ready="onReady"
          ref="videoPlayer"
        ></video-player>
      </div>
      <div class="player-column" v-if="pptVisible">
        <!-- ppt -->
        <ppt-player
          :index="pptIndex"
          :ppts="chatperResources.ppts"
          @close="onPPTClose"
          @fullscreen="onPPTFullscreen"
          @videoSyncTime="onVideoSyncTime"
        ></ppt-player>
      </div>
    </div>
    <div class="player-footer">
      <em class="player-button player-button-download" v-if="chapter.pdf">
        <a :href="chapter.pdf" download target="_blank">下载PPT</a>
      </em>
      <em :class="pptClass" @click="togglePPTVisible" v-if="chatperResources.ppts.length">同步显示PPT</em>
      <em :class="skipClass" @click="toggleSkip">始终跳过片头</em>
    </div>
  </div>
</template>

<script>
import Cookies from 'js-cookie'
import { throttle } from 'lodash'
// api
import * as api from '../../api'
// components
import videoPlayer from './videoPlayer.vue'
import pptPlayer from './pptPlayer.vue'

export default {
  name: 'ChapterPlayer',
  components: { videoPlayer, pptPlayer },
  props: {
    // 当前章节
    chapter: { type: Object },
    // 是否是PPT播放跳转
    isSeek: { type: Boolean, default: false },
    // PPT当前选中的索引
    pptIndex: { type: Number, default: 0 }
  },
  data() {
    // 是否跳过片头
    const isSkip = window.localStorage.getItem('isSkip') === 'true'
    return {
      videoVisible: true,
      pptVisible: false,
      isSkip,
      skipTime: 6,
      chatperResources: null,
      throttled: null,
      throttleWait: 5, // 秒
      progress: {
        cpt: 0, // 当前播放时间
        mpt: 0, // 当前播放最大时间
        progress: 0, // 进度
        pt: 0 // 累计观看时间
      },
      player: null,
      watchedTime: 0,
      watchedTimePoint: [] // 视频观看的时间点
    }
  },
  watch: {
    pptIndex(index) {
      this.isSeek && this.updateVideoCurrentTime(index)
    }
  },
  computed: {
    // 学期ID
    sid() {
      return this.$route.params.sid
    },
    // 课程ID
    cid() {
      return this.$route.params.cid
    },
    // 视频资源ID
    resourceId() {
      return this.chapter.resource_id
    },
    /**
     * 视频提供者
     * @return 1是CC加密; 2是非加密; 3是阿里云
     */
    videoProvider() {
      const video = this.chapter.video || {}
      return video.video_provider || 3
    },
    pptClass() {
      return {
        'player-button': true,
        'player-button-ppt': !this.pptVisible,
        'player-button-ppt__active': this.pptVisible
      }
    },
    skipClass() {
      return {
        'player-button': true,
        'player-button-skip': !this.isSkip,
        'player-button-skip__active': this.isSkip
      }
    }
  },
  methods: {
    // 同步显示PPT
    togglePPTVisible() {
      this.videoVisible = true
      this.pptVisible = !this.pptVisible
    },
    // 始终跳过片头
    toggleSkip() {
      this.isSkip = !this.isSkip
      window.localStorage.setItem('isSkip', this.isSkip)
    },
    // 关闭PPT
    onPPTClose() {
      this.pptVisible = false
      this.videoVisible = true
    },
    // PPT全屏
    onPPTFullscreen(value) {
      this.videoVisible = !value
    },
    // 设置视频时间为当前PPT时间
    onVideoSyncTime(time) {
      this.player.seek(time)
    },
    // 播放器ready
    onReady(player) {
      this.player = player
      // 跳转播放进度
      if (this.progress.cpt) {
        this.player.seek(this.progress.cpt)
      }
    },
    // 当前播放时间更新
    onTimeupdate(time) {
      time = Math.floor(time)
      const ppts = this.chatperResources.ppts || []
      let index = this.chatperResources.ppts.findIndex(item => item.ppt_point > time)
      index = index !== -1 ? index - 1 : ppts.length - 1
      this.$emit('change-ppt', index)
      const durations = this.player.getDuration()
      // 更新当前播放时间
      this.progress.cpt = time
      // 观看的最大点
      this.progress.mpt = Math.max(time, this.progress.mpt)
      const hasTimePoint = this.watchedTimePoint.includes(this.progress.cpt)
      if (!hasTimePoint) {
        this.watchedTimePoint.push(this.progress.cpt)
      }
      // 更新视频观看总时长
      this.updateWatchTime(time)
      // 更新视频进度，10秒更新一次
      if (this.throttled) {
        this.throttled(time, durations)
      } else {
        this.throttled = throttle(this.updateChapterVideoProgress, this.throttleWait * 1000, { leading: false })
      }
    },
    // 更新视频当前播放时间
    updateVideoCurrentTime() {
      const ppt = this.chatperResources.ppts[this.pptIndex]
      ppt && this.player.seek(ppt.ppt_point) // 增加2秒
    },
    // 获取章节视频详情
    getChapterVideo() {
      // 视频播放类型 1是CC加密; 2是非加密; 3是阿里云
      if (this.videoProvider === 3) {
        api.getChapterVideoAliyun(this.resourceId).then(response => {
          this.chatperResources = response
          Array.isArray(response.ppts) && this.$emit('pptupdate', response.ppts)
        })
      } else {
        api.getChapterVideo(this.resourceId).then(response => {
          let { video, audio, ppts } = response
          video = video.reduce(
            (result, item) => {
              if (item.quality === '10') {
                result.LD = item.playurl
              }
              if (item.quality === '20') {
                result.SD = item.playurl
              }
              return result
            },
            { LD: '', SD: '' }
          )
          this.chatperResources = { video, audio, ppts }
          Array.isArray(ppts) && this.$emit('pptupdate', ppts)
        })
      }
    },
    // 获取章节视频进度
    getChapterVideoProgress() {
      api
        .getChapterVideoProgress(this.sid, this.resourceId, {
          device_id: Cookies.get('_idt')
        })
        .then(response => {
          this.progress = response
          // 跳转播放进度
          if (this.player && response.cpt) {
            this.player.seek(response.cpt)
          }
        })
    },
    // 更新章节视频进度
    updateChapterVideoProgress(time, durations) {
      // 登录用户信息
      const user = window.G.UserInfo
      const params = {
        sid: user.student_info.id,
        uid: user.id,
        d: Cookies.get('_idt'),
        i: Cookies.get('_idt'),
        c: this.cid, // 课程ID
        s: this.sid, // 学期ID
        v: this.resourceId, // 视频资源ID
        _p: this.progress.pt, // 累计时间
        _m: this.progress.mpt, // 当前播放最大时间
        _c: this.progress.cpt, // 当前播放位置
        ps: this.watchedTimePoint.join(',') // 播放时，统计帧
      }
      api.updateChapterVideoProgress(params)
      // 清空已经上传过的观看时间点
      this.watchedTimePoint = []
    },
    // 更新观看总时长
    updateWatchTime(time) {
      if (time === this.watchedTime) {
        return
      }
      this.watchedTime = time
      // 增加跳过片头时间
      if (this.isSkip && !this.progress.pt) {
        this.progress.pt = this.skipTime + 20
      }
      // 默认增加时间
      this.progress.pt = this.progress.pt || 20
      this.progress.pt++
    }
  },
  beforeMount() {
    // 获取视频
    this.getChapterVideo()
    // 获取视频进度
    this.getChapterVideoProgress()
  }
}
</script>

<style lang="scss" scoped>
.player {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  background-color: #3f3f3f;
}
.player-main {
  display: flex;
  flex: 1;
  overflow: hidden;
}
.player-column {
  flex: 1;
  height: 100%;
}
.player-footer {
  display: flex;
  align-items: center;
  height: 54px;
  padding: 0 20px;
  font-size: 14px;
  color: #a0a0a0;
  a {
    color: #a0a0a0;
    text-decoration: none;
  }
  em {
    margin-right: 40px;
    cursor: pointer;
  }
}
.player-button {
  display: inline-block;
  color: #a0a0a0;
  padding-left: 25px;
  font-size: 14px;
  line-height: 18px;
  margin: 0 20px;
  background: url(../../assets/play-icons.png) no-repeat 0 0;
  cursor: pointer;
}
.player-button-download {
  background-position: 0 -240px;
}
.player-button-ppt {
  background-position: 0 -240px;
}
.player-button-ppt__active {
  background-position: 0 -280px;
  color: #b19241;
}
.player-button-skip {
  background-position: 0 -160px;
}
.player-button-skip__active {
  background-position: 0 -200px;
  color: #b19241;
}
</style>
