<template>
  <div>
    <h2 class="tc">
      <span style="float: left;" v-if="nextFaceTick" >
        <span style="font-size: 10px;">倒计时：{{nextFaceTick}}S</span>
      </span>
      <span>{{curTimes|useTime}}</span>
      <strong>/</strong>
      <span>{{media.duration|useTime}}</span>
    </h2>
    <el-row style="width: 1100px;">
      <el-col :span="18" style="width:680px;">
        <div style="height: 540px;">
        <video-player id="myVideo" class="video-player-box" ref="videoPlayer"
          @pause="onPlayerPause($event)"
          @play="onPlayerStart($event)"
          @ready="playerReadied"
          @timeupdate="onPlayerTimeupdate($event)" @ended="onPlayerEnded($event)" :globalOptions="{controls:true}"
          :options="options">
        </video-player>
        </div>

        <div class="tc">
             <p  v-if="errMsg" style="font-size: 30px;color: red;"> {{errMsg}}</p>
        </div>

      </el-col>

      <el-col :span="6" style="width: 420px;float:right;">
        <div class="account-tit2">
          <a :class="{'current':required===1}" @click="required=1" style="width: 100px;">必修课程</a>
          <a :class="{'current':required===0}" @click="required=0" style="width: 100px;">选修课程</a>
          <a :class="{'current':required===2}" @click="required=2" style="width: 100px;">讨论区</a>
        </div>


        <el-menu v-if="required==1" style="width: 400px;font-size: 10px;">
          <ul class="m-chapter-list">
            <li v-for="(item, index) in chapter.required" :key="index" :class="{'current':item.name==activeChapter}">
              <a href="javascript:void(0)" style="text-decoration: none" @click="goState(item)" class="ng-binding">
                {{parseInt(item.xs/10)}}学时 {{item.name}}</a>

              <div class="sub-list" v-if="item.name==activeChapter">
                <a v-for="(subItem,index)  in list" :key="subItem.id" v-if="subItem.chapterName == activeChapter"
                  @click="goSubState(subItem, index)" :class="{'current':subItem.name==activeName}">
                  <span class="media-process">
                    <el-progress :percentage="subItem.percent" type="circle" :width="16" :height="16"
                      :format="()=>{return ''}" v-if="subItem.percent>=100" color="green"></el-progress>
                    <el-progress :percentage="subItem.percent" type="circle" :width="16" :height="16"
                      :format="()=>{return ''}" v-else-if="subItem.percent>=50" color="cyan"></el-progress>
                    <el-progress :percentage="subItem.percent" type="circle" :width="16" :height="16"
                      :format="()=>{return ''}" v-else></el-progress>
                  </span>
                  <span class="media-name"> {{subItem.name}} </span>
                </a>
              </div>
            </li>
          </ul>
        </el-menu>

        <el-menu v-if="required==0">
          <ul class="m-chapter-list" style="width: 400px;font-size: 10px;">
            <li v-for="(item, index) in chapter.normal" :key="index" :class="{'current':item.name==activeChapter}">
              <a href="javascript:void(0)" style="text-decoration: none" @click="goState(item)"
                class="ng-binding">{{parseInt(item.xs/10)}}学时 {{item.name}}</a>

              <div class="sub-list pt10" v-if="item.name==activeChapter">
                <a v-for="(subItem,index) in list" :key="subItem.id" v-if="subItem.chapterName == activeChapter"
                  @click="goSubState(subItem, index)" :class="{'current':subItem.name==activeName}">
                  <span class="media-process">
                    <el-progress :percentage="subItem.percent" type="circle" :width="16" :height="16"
                      :format="()=>{return ''}" v-if="subItem.percent>=100" color="green"></el-progress>
                    <el-progress :percentage="subItem.percent" type="circle" :width="16" :height="16"
                      :format="()=>{return ''}" v-else-if="subItem.percent>=50" color="cyan"></el-progress>
                    <el-progress :percentage="subItem.percent" type="circle" :width="16" :height="16"
                      :format="()=>{return ''}" v-else></el-progress>
                  </span>
                  <span  class="media-name"> {{subItem.name}} </span>
                </a>
                </a>
              </div>
            </li>
          </ul>
          <!-- <el-menu-item v-for="item in chapter.normal" :key="item">{{item}}</el-menu-item> -->
        </el-menu>

        <div v-if="required==2">
          <i-message :media-id="media.mediaId"></i-message>
        </div>

      </el-col>

    </el-row>

   <el-dialog  title="开始人脸认证" center :visible.sync="identifyFaceDialog" width="540px"
   :show-close="false"
      :close-on-click-modal = "false" :append-to-body="true" >
      <div>
        <i-collect :updateTime="updateTime" @getface="getface" />
        <div class="tc m20">
          <p  v-if="errMsg" style="font-size: 30px;color: red;"> {{errMsg}}</p>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
  import {
    httpServer
  } from "@/components/httpServer/httpServer.js";
  import md5 from 'js-md5';
  import {
    videoPlayer
  } from 'vue-video-player';
  import IMessage from '@/components/message/iMessage.vue'
  import ICollect from '@/components/face/iCollect.vue'
  import 'video.js/dist/video-js.css'
  import {
    MessageBox
  } from "element-ui";
  export default {
    name: "Index",
    data() {
      return {
        timer: false,
        required: 1,
        tickNum: 0,
        prevTime: 0,
        isReady: false,
        nextFaceTick: 0,
        identifyFaceDialog: false,
        startPlay: false,     // 开始认证
        nextFaceTime: 0,
        faceInterval: 10,     // 打开人脸时间
        closeDailogTime: 20,  // 关闭dialog时间
        onIdentify: false,    // 同一时间一个认证
        identifyDuration: 180*1000,
        activeChapter: '',
        activeName: '',
        curTimes: 0,
        errMsg: '',
        prevCollect: 0,
        updateTime: 0,
        imgbase64: '',
        onPlay: false,
        loading: false
      }
    },
    components: {
      videoPlayer,
      IMessage,
      ICollect
    },
    props: ['media', 'options', 'heartbeat', 'maxErrorCount', 'collectBeat', 'closeFace', 'chapter', 'list'],
    filters: {
      useTime(val) {
        let timestr = ""
        let hour = parseInt(val / 3600);
        let min = parseInt(val / 60 % 60);
        let sec = parseInt(val % 60);
        if (hour < 10) hour = "0" + hour;
        if (min < 10) min = "0" + min;
        if (sec < 10) sec = "0" + sec;
        return hour + ":" + min + ":" + sec
      }
    },
    beforeDestroy() {
      this.stopTick()
      this.reportErr("play", 'destroy');
    },
    computed: {
      player() {
        return this.$refs.videoPlayer.player
      }
    },
    beforeDestroy() {
      this.destroyTimer()
    },
    created() {
      this.startMonitor();
      this.activeChapter = this.media.chapterName;
      this.activeName = this.media.name
    },
    watch: {
      "media.name"() {
        this.activeChapter = this.media.chapterName;
        this.activeName = this.media.name
        this.tickNum = 0
        this.errMsg = ''
        this.prevCollect = 0;
        this.startIdentify()
        this.setposition( this.media.position )
      }
    },
    methods: {
      getface( val){
        this.imgbase64 = val;
        let now = parseInt( Date.now()/2000 );
        // 人脸认证期间， 一秒一次
        if( !this.identifyFaceDialog && this.prevCollect != now ){
          this.prevCollect = now
          this.photograph("video")
        }
      },
      handler_msg(pause, msg ){
        this.errMsg = msg || '';
        if ( !msg ) {
          this.identifyPassAndPlay()
        }
      },
      photograph( ref ) {
        // 认证窗口关闭
        if( !this.identifyFaceDialog  ){
          return;
        }
        // 取不到base64
        if( !this.imgbase64 ){
          this.handler_msg(false, "人脸定位中...." );
          return;
        }
        // 用户在认证中
        if( this.onIdentify ){
          return;
        }
        this.onIdentify = true;
        let param = {
          id: this.media.id,
          ref,
          image: this.imgbase64
        }
        this.imgbase64 = '';
        httpServer("course.collect", param).then(res => {
          let {
            msg,
            pause
          } = res.data
          this.onIdentify = false;
          this.handler_msg(pause, msg )
        })
      },
      destroyTimer() {
        if (this.timer) clearTimeout(this.timer);
      },
      goState(item) {
        if (item.name == this.activeChapter) {
          this.activeChapter = ""
        } else {
          this.activeChapter = item.name;
        }
      },
      goSubState(item, index) {
        this.$emit('loadMedia', item, index)
      },
      startTick() {
        console.log( "startTick")
        let tick = this.tryTick;
        this.destroyTimer();
        this.tickNum = 0;
        this.timer = setTimeout(tick, 1 * 1000);
      },
      stopTick() {
        console.log( "stopTick")
        this.errMsg = '';
        if (this.timer) clearInterval(this.timer);
      },
      tryTick() {
        let that = this;
        try {
          that.tick()
        } catch (err) {
          that.reportErr("play", '' + err.message)
        }
        this.destroyTimer()
        this.timer = setTimeout(this.tryTick, 1 * 1000);
      },
      playerReadied(audio) {
        let that = this;
        let {
          position,
          duration
        } = this.media
        if (position > 5 && position < duration) {
          setTimeout(() => {
            this.setposition(position)
          }, 2000)
        }
        this.isReady = true
      },
      onPlayerTimeupdate(player) {
        let curTimes = player.cache_.currentTime;
        if (curTimes > 30 && curTimes > this.curTimes + 2) {
          player.currentTime(this.curTimes);
          return;
        }
        this.curTimes = curTimes
      },
      setposition(position) {
        if (position > this.media.duration) position = this.media.duration;
        let player = this.$refs.videoPlayer.player;
        let res = player.currentTime(position);
        // player.load();
        this.curTimes = position;
        if (this.media.isFinish) return;
        if (this.media.position >= this.media.duration - 2*this.heartbeat && !this.media.isFinish) {
          this.tick(true)
        }
      },
      onPlayerPause(event) {
        this.reportErr("play", 'pause');
        this.onPlay = false
      },
      onPlayerEnded(event) {
        this.reportErr("play", 'end');
        this.tick(true)
      },
      onClose() {
        this.reportErr("play", 'close')
        this.doPause()
        this.$emit("close")
      },
      doPause() {
        this.onPlay = false
        setTimeout( ()=>{
          let myPlayer = this.$refs.videoPlayer.player;
          myPlayer && myPlayer.pause()
        }, 20);
        // console.log( myPlayer )
        // myPlayer&& myPlayer.controlBar.hide()
      },
      doPlay() {
        this.onPlay = true
        this.startTick();
        if (!this.$refs.videoPlayer || !this.$refs.videoPlayer.player) return;
        let myPlayer = this.$refs.videoPlayer.player;
        myPlayer && myPlayer.play()
        this.tickNum = 0
      },
      onPlayerStart( player ) {
        this.onPlay = true
        this.startPlay  = true;
        let now = Date.now()
        if(  now > this.nextFaceTime ){
          this.startIdentify()
          return
        }
        this.reportErr("play", 'start');
        this.startTick();
      },
      startIdentify(){
        // 清空上一次遗留
        this.imgbase64 = '';
        let isDebug = false
        if( !this.closeFace){
          this.nextFaceTick = 0;
          this.identifyFaceDialog = true
          this.updateTime = Date.now()
          // 人脸采集间隔时间
          this.faceInterval = this.heartbeat * this.collectBeat*1000;
          // 关闭时间
          this.closeDailogTime = this.updateTime +  this.identifyDuration;
          //
          if( isDebug){
            this.faceInterval = 30*1000;
            this.closeDailogTime = this.updateTime + 30*1000;
          }
          // 关闭播放
          setTimeout( ()=>{
            let myPlayer = this.$refs.videoPlayer.player;
            myPlayer && myPlayer.pause()
          }, 200);
        }
        this.startTick()
      },
      identifyPassAndPlay(){
        //  认证通过 关闭dialog
        this.identifyFaceDialog = false
        //  下一次人脸采集时间
        this.nextFaceTime = Date.now() + this.faceInterval
        // 通过 开始播放
        this.$message.successMsg("人脸认证通过", 2)
        this.errMsg = ''
        this.doPlay()
      },
      reportErr(action, msg) {
        httpServer("course.report", {
          action,
          msg
        })
      },
      startMonitor() {
        let that = this
        document.addEventListener("visibilitychange", function() {
          // || document.hidden
          if (document.visibilityState == "hidden") {
            // that.doPause( )
            that.reportErr("play", 'hidden');
          } else {
            that.reportErr("play", 'show');
            // that.doPlay()
          }
        });
      },

      tick(force = false) {
        let media = this.media;
        this.tickNum++
        let now = Date.now()
        // 人脸认证期间 关闭播放

        if( !this.closeFace ){
            this.nextFaceTick = 0;
            //
            if( this.identifyFaceDialog  ) {
              // 在播放中，关闭播放
              if( this.onPlay ){
                this.doPause()
              }
              // 主动关闭人脸认证
              if( now > this.closeDailogTime ){
                this.$message.errorMsg("人脸检测失败，暂停播放", 5);
                this.errMsg = "人脸检测失败，暂停播放";
                // 关闭定时器
                this.startPlay = false;
                //  认真失败，下一次播发需要人脸
                this.nextFaceTime = now
                this.stopTick();
                this.identifyFaceDialog = false;
              }else{
                // 人脸认证
                this.photograph("video")
              }
              return;
            }else{
              console.log("next",(now - this.nextFaceTime)/1000 )
              if( !this.startPlay  ){
                this.stopTick()
                return;
              }
              if( now > this.nextFaceTime  ){
                this.startIdentify();
                return;
              }
              this.nextFaceTick = parseInt( (this.nextFaceTime-now  )/1000);
            }
        }
        // 未开始
        if(!force && !this.onPlay ){
          return;
        }
        // 已经完成
        if (this.media.isFinish) {
          console.log("finish")
          return;
        }

        // 每5秒一次心跳
        if (this.tickNum % this.heartbeat != 0) {
          return;
        }

        // 主动暂停
        let myPlayer = this.$refs.videoPlayer.player;
        let curTimes = parseInt(myPlayer.currentTime());
        // 后退无心跳
        if( !force ){
          if (curTimes < this.media.position+this.heartbeat) {
            return;
          }
        }

        let isFinish = force ? 1 : 0
        if (curTimes >= media.duration) isFinish = 1;
        //  拉到后面
        if (!isFinish) {
          if (!this.onPlay) return;
        }
        // 强制完成
        let param = {
          id: media.id,
          position: curTimes,
          isFinish
        };
        httpServer("course.tick", param, true).then(res => {
          if (res.code == 200) {
            let {
              skip,
              position,
              pause,
              closed
            } = res.data
            if (pause || closed) {
              this.doPause();
              // 服务器关闭播放
              this.startPlay = false;
              this.stopTick()
              this.$emit("close")
              if (closed) {
                this.$message.errorMsg("课程关闭学习", 5);
              } else if (pause) {
                this.$message.errorMsg("多处同时播放视频", 5);
              }
              return
            }
            if (!skip) {
              setTimeout(() => {
                this.setposition(position)
              }, 2000);
            };

            Object.assign(param, res.data)
            this.$emit("update", param)
          }
        })
      }
    }
  }
</script>

<style>
  @import url("./imedia.css");

  .video-js {
    .vjs-control-bar {
      .vjs-icon-custombutton {
        font-family: VideoJS;
        font-weight: normal;
        font-style: normal;
      }

      .vjs-icon-custombutton:before {
        content: "\f108";
        font-size: 1.8em;
        line-height: 1.67;
      }
    }
  }

  .left-float {
    width: 240px;
    height: 180px;
    background-color: #8bbdf5;
    position: fixed;
    transition: bottom ease .9s;
    z-index: 0;
    left: 60px;
    top: 120px;
    text-align: center;
    border-radius: 5px;
  }

  .center-float-dialog {
    width: 240px;
    height: 180px;
    background-color: #8bbdf5;
    position: fixed;
    transition: bottom ease .9s;
    z-index: 0;
    left: 40%;
    top: 200px;
    /* margin: 120px auto; */
    text-align: center;
    border-radius: 5px;
  }

  .left-float-dialog{
    width: 240px;
    height: 180px;
    /* background-color: #8bbdf5; */
    position: fixed;
    transition: bottom ease .9s;
    z-index: 0;
    left: 20px;
    top: 140px;
    text-align: center;
    border-radius: 5px;
  }


  .p-process {
    width: 100%;
    margin: 20px auto;
    height: 30px;
  }

  .media-footer {
    padding: 0px 30px;
    text-align: left;
    line-height: 40px !important;
    bottom: -10px;
  }

  .media-center {
    text-align: center;
    padding: 0px;
  }

  .media-time {
    font-size: 18px;
    vertical-align: center;
  }

  .media-select {
    white-space: nowrap;
    text-align: right;
    line-height: 40px !important;
    float: right;
    margin: 0px !important;
  }

  .bicon {
    font-size: 28px !important;
    padding: 4px !important;
  }

  .media-el-select {
    font-size: 28px !important;
    width: 80px;
    padding: -4px auto !important;
  }
  .media-name {
    width: 300px;
    margin-left: 16px;
    line-height: 24px;
    white-space: nowrap;
    overflow: hidden;
    align-items: center;
    text-overflow: ellipsis;
  }
  .media-process{
    width: 8px;
    height: 8px;
    align-items: center;
  }

  .vjs-tech {
    pointer-events: none;
  }
</style>
