<template>
  <div
    id="videoCy"
    :style="{
      backgroundImage: `url(${$tools.splitImgHost(goodsData.coverUrl, false)})`
    }"
  >
    <div id="player" v-show="!HideVideo"></div>
    <div class="recordStyle" v-if="showRecordStatus">
      您上次看{{
        $tools.secondToTime(this.activeSection.videoCurrentTime || 0)
      }},正在自动续播
      <span class="videoCurrentTime_style">|</span>
      <span class="btn_sty" @click="seekVideo0">从头播放</span>
    </div>
    <takePicture
      ref="takePicture"
      @returnParameter="returnParameter"
    ></takePicture>
    <count-down ref="countDown" @againSubmit="postStudyRecord(1)"></count-down>
  </div>
</template>

<script>
import takePicture from "@/components/takePicture/index.vue";
import countDown from "@/components/countDown/index.vue";
export default {
  components: { takePicture, countDown },
  inject: ["getGoodsData"],
  props: {
    activeSection: {
      type: Object,
      default: () => {
        return {};
      } //当前节数据
    }
  },
  data() {
    return {
      vodPlayerJs: "https://player.polyv.net/script/player.js",
      player: null,
      HideVideo: false, //是否隐藏播放器
      photoList: [], //抓拍时间拍照数组
      photoHistoryList: [], //历史和已拍照数据
      photoIndex: 0, //当前拍照对应索引
      showRecordStatus: false, //是否显示从头播放提示
      showRecordSetTimeOut: null, //从头播放提示计时器函数
      openPhotoStatus: 0, //暂存学习状态
      commitTime: null, //暂存时间-节流
      commitTimePhoto: null, //判断拍照时刻-节流
      videoPauseSetTimeout: null, //定时器停留太久触发
      failToRegister: false, //报名推送不通过
      videoPauseSetTimeStatus: false
    };
  },
  computed: {
    goodsData() {
      return this.getGoodsData();
    }
  },
  watch: {
    //因为刚开始获取不到goodsData的数据 所以需要监听
    goodsData: function(newVal, oldVal) {
      if (newVal) {
        this.getBeforeWork(); //处理前置任务
      }
    }
  },
  created() {
    if (!window.polyvPlayer) {
      const myScript = document.createElement("script");
      myScript.setAttribute("src", this.vodPlayerJs);
      myScript.onload = () => {
        console.log("加载成功");
      };
      document.body.appendChild(myScript);
    }
  },
  mounted() {
    this.$bus.$on("toPlay", async item => {
      if (this.player) {
        this.player.destroy(); //初始化播放器
      }
      this.initData(); //初始化参数
      await this.getRecordHistoryPhoto(); //获取拍照历史记录
      await this.getRecordLast(); //获取播放记录
      await this.loadPlayer(); //加载播放内容
      this.player.on("s2j_onPlayerInitOver", () => {
        this.player.on("s2j_onPlayStart", this.onPlayStatus); //视频初次播放时触发
        this.player.on("s2j_onVideoPause", this.onVideoPause); //视频暂停时触发
        this.player.on("s2j_onVideoPlay", this.onVideoPlay); //视频初次播放或由暂停恢复播放时触发
        this.player.on("s2j_onPlayOver", this.onPlayOver); //当前视频播放完毕时触发
        this.player.on("s2j_onPlayerError", this.onPlayerError); //播放出现错误时触发
        this.player.on("serverError", this.serverError); //发生业务逻辑错误时触发，比如授权验证失败、域名黑白名单验证不通过等错误。参数返回事件名称和错误代码。
      }); //播放器初始化完毕时触发。播放器提供的方法需要在此事件发生后才可以调用。
    });
    // document.addEventListener("visibilitychange", this.pauseVideo);
  },
  methods: {
    getBeforeWork() {},
    //初始化参数
    initData() {
      this.commitTime = null;
      this.commitTimePhoto = null;
      this.openPhotoStatus = 0;
      this.videoPauseSetTimeStatus = false;
      clearTimeout(this.videoPauseSetTimeout); //删除暂停计算拍照定时器
    },
    //获取播放记录
    getRecordLast() {
      return new Promise(resolve => {
        clearTimeout(this.showRecordSetTimeOut);
        let data = {
          orderGoodsId: this.goodsData.orderGoodsId,
          gradeId: this.goodsData.gradeId,
          goodsId: this.goodsData.goodsId,
          courseId: this.activeSection.courseId,
          moduleId: this.activeSection.moduleId,
          chapterId: this.activeSection.chapterId,
          sectionId: this.activeSection.sectionId
        };
        this.$request.recordLast(data).then(res => {
          if (
            res.data &&
            res.data.videoCurrentTime &&
            res.data.videoCurrentTime - 3 >= 0
          ) {
            this.activeSection.videoCurrentTime = res.data.videoCurrentTime - 3;
          }
          resolve();
        });
      });
    },
    //从头播放
    seekVideo0() {
      this.player.j2s_seekVideo(0);
      this.showRecordStatus = false;
    },
    //获取拍照历史记录
    getRecordHistoryPhoto() {
      return new Promise(resolve => {
        var data = {
          sectionId: this.activeSection.sectionId,
          goodsId: this.goodsData.goodsId,
          courseId: this.activeSection.courseId,
          gradeId: this.goodsData.gradeId,
          orderGoodsId: this.goodsData.orderGoodsId,
          chapterId: this.activeSection.chapterId,
          moduleId: this.activeSection.moduleId
        };
        this.$request.getPhotoLastRecord(data).then(res => {
          //清空历史数据
          this.photoList = [];
          this.photoHistoryList = [];
          this.photoIndex = 0;
          for (let i = 0; i < res.data.length; i++) {
            //-2存储随机拍照数组
            if (res.data[i].photoIndex == -2 && res.data[i].timeInterval) {
              this.photoList = res.data[i].timeInterval.split(",");
            } else {
              this.photoHistoryList.push(res.data[i].photoIndex);
            }
          }
          resolve();
        });
      });
    },
    //计算拍照逻辑
    photoLogic() {
      if (this.photoList.length > 0 || this.activeSection.learning == 1) return; //已从历史拍照数据获得
      var polyvPlayerContext = this.player;
      let totalVideoTime = polyvPlayerContext.j2s_getDuration();
      let duration = polyvPlayerContext.j2s_getCurrentTime();
      if (this.goodsData.erJianErZao) {
        this.photoList = this.randomConfig(totalVideoTime, duration);
      } else if (this.goodsData.jjShiGongYuan && this.goodsData.orderYears) {
        this.photoList = this.ShiPhotoList(totalVideoTime, duration);
      } else if (this.goodsData.goodsPhotographConfig.photoNum > 0) {
        this.photoList = this.getPhotoList(
          totalVideoTime,
          this.goodsData.goodsPhotographConfig.photoNum
        );
      }
      //兼容已有观看历史
      for (let i = 0; i < this.photoList.length - 1; i++) {
        if (this.photoList[i] < duration && this.photoList[i + 1] > duration) {
          this.photoIndex = i + 1;
          break;
        }
        if (duration > this.photoList[this.photoList.length - 1]) {
          this.photoIndex = this.photoList.length - 1; //取最后一个下标
          break;
        }
      }
    },
    //普通拍照
    getPhotoList(totalVideoTime, photoNum) {
      let photoList = [];
      if (totalVideoTime >= 900) {
        //大于15分钟
        if (photoNum == 1) {
          //开头拍1张
          photoList.push(1);
        } else if (photoNum == 3) {
          //拍3张
          photoList.push(0); //开头拍一张
          let centerTime = Math.floor(totalVideoTime / 2); //获取中间时间
          let centerMinTime = centerTime - 300; //前后5分钟
          let centerMaxTime = centerTime + 300;
          let centerTakeTime = this.randomNum(centerMinTime, centerMaxTime);
          photoList.push(centerTakeTime); //中间拍一张
          let endMaxTime = totalVideoTime - 60;
          let endMinTime = totalVideoTime - 300;
          let endTakeTime = this.randomNum(endMinTime, endMaxTime);
          photoList.push(endTakeTime); //最后拍一张
        }
      } else {
        //小于15分钟，只拍前后各一张
        if (photoNum == 1) {
          //开头拍1张
          photoList.push(1);
        } else if (photoNum == 3) {
          photoList.push(1);
          let centerTime = this.randomNum(
            (1 / 3) * totalVideoTime,
            (2 / 3) * totalVideoTime
          );
          photoList.push(centerTime);
          let endTakeTime = this.randomNum(
            (2 / 3) * totalVideoTime,
            totalVideoTime
          );
          photoList.push(endTakeTime);
        }
      }
      this.postCoursePhotoRecord(true); //提交随机拍照时间数组
      return photoList;
    },
    //施工继教
    ShiPhotoList(totalVideoTime) {
      //施工继教带年份的订单拍照设置
      let time1 = 50 * 60; //拍照间隔多久一张 50分钟
      let num = Math.trunc(totalVideoTime / time1) + 1; //拍照数量
      let photoList = [];
      for (let i = 0; i < num; i++) {
        photoList.push(i * time1);
      }
      return photoList;
    },

    // 随机拍摄时间（二建）
    randomConfig(totalVideoTime, duration) {
      this.photoHistoryList = [];
      let photoList = [duration];
      let pre = duration;
      if (totalVideoTime > 300) {
        while (pre <= totalVideoTime) {
          pre += this.randomNum(780, 900);
          pre <= totalVideoTime && photoList.push(pre);
        }
        if (totalVideoTime - 300 > photoList.slice(-1)[0]) {
          photoList.push(this.randomNum(totalVideoTime - 180, totalVideoTime));
        }
      }
      return photoList;
    },
    //postTime = true 只提交随机时间 false 提交拍照
    postCoursePhotoRecord(postTime = false, photoUrl) {
      return new Promise((resolve, reject) => {
        let currentTime = this.player.j2s_getCurrentTime();
        let data = {
          goodsId: this.goodsData.goodsId,
          gradeId: this.goodsData.gradeId,
          orderGoodsId: this.goodsData.orderGoodsId,
          courseId: this.activeSection.courseId,
          moduleId: this.activeSection.moduleId,
          chapterId: this.activeSection.chapterId,
          sectionId: this.activeSection.sectionId,
          photo: postTime ? "" : photoUrl,
          photoTime: parseInt(currentTime > 0 ? currentTime : 0),
          photoIndex: postTime ? -2 : parseInt(this.photoIndex), //从0算起,-2只提交随机时间
          photoNum: parseInt(this.goodsData.goodsPhotographConfig.photoNum),
          timeInterval: postTime ? this.photoList.join(",") : ""
        };
        this.$request
          .coursePhotoRecord(data)
          .then(res => {
            resolve(res);
          })
          .catch(err => {
            reject();
          });
      });
    },
    //随机拍摄时间
    randomNum(minNum, maxNum) {
      switch (arguments.length) {
        case 1:
          return parseInt(Math.random() * minNum + 1, 10);
          break;
        case 2:
          return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
          break;
        default:
          return 0;
          break;
      }
    },
    // 播放视频
    loadPlayer() {
      return new Promise(resolve => {
        var self = this;
        const polyvPlayer = window.polyvPlayer;
        self.$request
          .obtainpolyvvideosign(self.activeSection.recordingUrl)
          .then(res => {
            const autoPlay = self.goodsData.goodsPlayConfig
              ? self.goodsData.goodsPlayConfig.autoPlay
              : true;
            const isAllowSeek = self.goodsData.goodsPlayConfig
              ? self.goodsData.goodsPlayConfig.isAllowSeek
              : "on";
            const playbackRate = self.goodsData.goodsPlayConfig
              ? self.goodsData.goodsPlayConfig.playbackRate
              : false;
            self.player = polyvPlayer({
              wrap: "#player",
              width: 810,
              height: 455,
              preventKeyboardEvent: true, //是否屏蔽键盘事件，为true时屏蔽。
              showLine: true, //是否显示线路选择按钮
              ban_history_time: "on", //是否禁用续播功能，取值：{on,off}。
              vid: self.activeSection.recordingUrl,
              autoplay: autoPlay, //	是否自动播放。
              ban_seek: isAllowSeek, //是否禁止拖拽进度条，取值：{on,off}。
              speed: playbackRate, //当speed参数值为boolean类型时，代表是否显示倍速切换的按钮。
              teaser_show: 1, //是否播放片头：0 不播放，1 播放。片头可在管理后台进行设置。
              tail_show: 1, //是否播放片尾：0 不播放，1 播放。片尾可在管理后台进行设置。
              hideSwitchPlayer: true, //是否隐藏H5和Flash播放器的切换按钮。
              watchStartTime: self.activeSection.videoCurrentTime || 0, // 播放开始时间，表示视频从第几秒开始播放，参数值需小于视频时长。
              ts: res.data.ts, //移动播放加密视频需传入的时间戳。
              sign: res.data.sign, //移动端播放加密视频所需的签名。
              playsafe: function(vid, next) {
                self.$request.obtainpolyvvideopcsign(vid).then(res => {
                  next(res.data);
                });
              } //PC端播放加密视频所需的授权凭证。
            });
            self.$emit("videoScript", this.player); //抛出播放实例
            resolve();
          });
      });
    },
    //监听器
    timeEvent() {
      // 定时提交学习记录
      this.submitStudyRecords();
      //拍照监听执行
      let time = new Date().getTime();
      if (time >= this.commitTimePhoto) {
        this.watchPhoto();
        this.commitTimePhoto = time + 1000;
      }
    },
    //拍照监听执行
    watchPhoto() {
      if (
        this.photoList.length == 0 ||
        this.activeSection.learning == 1 ||
        this.$refs.takePicture.takePhotoModal ||
        this.failToRegister
      )
        return;
      let videoTime = this.player.j2s_getCurrentTime();
      let photoTime = 0; //获取拍照秒数
      for (let i = 0; i < this.photoList.length; i++) {
        photoTime = Number(this.photoList[i]); //获取拍照秒数
        if (photoTime < videoTime && photoTime > videoTime - 8) {
          //3秒区间内才触发拍照，避免拉动滚动条
          if (
            this.photoHistoryList.indexOf(i) < 0 &&
            this.activeSection.learning != 1
          ) {
            //不存在拍照历史，没有重修过，没有学过，则拍照
            this.player.j2s_pauseVideo(); //暂停
            this.photoIndex = i;
            this.openPhoto(); //启动拍照
          }
        }
      }
    },
    // 定时提交学习记录
    submitStudyRecords() {
      let time = new Date().getTime();
      if (time >= this.commitTime) {
        this.postStudyRecord(0);
        this.commitTime = time + 15000;
      }
    },
    //视频初次播放时触发
    onPlayStatus() {
      //计算拍照逻辑
      this.photoLogic();
      //开启上次播放位置提示
      if (this.activeSection.videoCurrentTime) {
        this.showRecordStatus = true;
        this.showRecordSetTimeOut = setTimeout(() => {
          this.showRecordStatus = false;
        }, 5000);
      }
      this.player.HTML5.video.addEventListener("timeupdate", this.timeEvent); //监听器
      console.log("视频初次播放时触发", this.player.j2s_getCurrentTime());
    },
    //视频暂停时触发
    onVideoPause() {
      if (
        this.activeSection.learning != 1 &&
        this.goodsData.erJianErZao &&
        !this.failToRegister
      ) {
        this.videoPauseSetTimeout = setTimeout(() => {
          if (this.isFullScreen()) {
            this.exitFullscreen();
          }
          this.videoPauseSetTimeStatus = true;
          this.$confirm(
            "检测播放暂停或拍照停留时间过长，刷新当前页面",
            "提示",
            {
              confirmButtonText: "确定",
              cancelButtonText: "取消",
              showCancelButton: false,
              closeOnClickModal: false,
              closeOnPressEscape: false,
              showClose: false,
              type: "warning"
            }
          )
            .then(() => {
              this.$router.go(0);
            })
            .catch(() => {});
        }, 300000); //300000
      }
    },
    //视频恢复播放时触发
    onVideoPlay() {
      if (
        this.activeSection.learning != 1 &&
        this.goodsData.erJianErZao &&
        !this.failToRegister
      ) {
        clearTimeout(this.videoPauseSetTimeout);
      }
      console.log("视频恢复播放时触发");
    },
    //当前视频播放完毕时触发
    onPlayOver() {
      this.$message({
        type: "success",
        message: "播放完毕"
      });
      this.isFullScreen();
      clearTimeout(this.videoPauseSetTimeout); //删除暂停计算拍照定时器
      this.postStudyRecord(1);
      console.log("当前视频播放完毕时触发");
    },

    //判断是全屏则退出全屏
    isFullScreen() {
      if (!!(document.webkitIsFullScreen || this.fullele())) {
        try {
          var de = document;
          if (de.exitFullscreen) {
            de.exitFullscreen();
          } else if (de.mozCancelFullScreen) {
            de.mozCancelFullScreen();
          } else if (de.webkitCancelFullScreen) {
            de.webkitCancelFullScreen();
          }
        } catch (err) {}
      }
    },
    fullele() {
      return (
        document.fullscreenElement ||
        document.webkitFullscreenElement ||
        document.msFullscreenElement ||
        document.mozFullScreenElement ||
        null
      );
    },
    //播放出现错误时触发
    onPlayerError() {
      this.$message.error("播放出现错误时触发");
    },
    //发生业务逻辑错误
    serverError() {
      this.$message.error("发生业务逻辑错误");
    },
    //启动拍照
    openPhoto() {
      if (this.isFullScreen()) {
        this.exitFullscreen();
      }
      this.$refs.takePicture.openPhoto();
      this.HideVideo = true;
    },
    //拍照成功回显 url
    async returnParameter(url) {
      this.HideVideo = false;
      let compareFaceData = await this.faceRecognition(url);
      if (compareFaceData >= 80) {
        let file = this.$tools.convertBase64UrlToBlob(url);
        const photoUrl = await this.$upload.upload(file, 0, {
          gradeId: this.goodsData.gradeId,
          orderGoodsId: this.goodsData.orderGoodsId
        });
        this.postCoursePhotoRecord(false, photoUrl)
          .then(async res => {
            this.photoHistoryList.push(this.photoIndex);
            const STATUS = await this.postStudyRecord(
              0,
              photoUrl,
              compareFaceData
            ); //提交记录
            //恢复播放
            if (STATUS) {
              var polyvPlayerContext = this.player;
              if (polyvPlayerContext && this.openPhotoStatus !== 1) {
                polyvPlayerContext.j2s_resumeVideo();
              }
            }
          })
          .catch(err => {
            this.$message({
              type: "warning",
              message: "上传接口报错，请重新拍照上传"
            });
            setTimeout(() => {
              this.openPhoto();
            }, 1500);
          });
      } else {
        this.$message({
          type: "warning",
          message: "人脸匹配不通过，请重新拍照上传"
        });
        setTimeout(() => {
          this.openPhoto();
        }, 1500);
      }
    },

    /**
     * 提交观看记录
     * status 1 学完 0未学完
     */
    postStudyRecord(status = 0, imgUrl, compareFaceData) {
      return new Promise((resolve, reject) => {
        let currentTime = 0;
        let PlayDuration = 0;
        var polyvPlayerContext = this.player;
        if (polyvPlayerContext) {
          currentTime = polyvPlayerContext.j2s_getCurrentTime(); //当前视频播放时刻
          PlayDuration = polyvPlayerContext.j2s_realPlayVideoTime(); //本次看的时长
        }
        let data = {
          orderGoodsId: parseInt(this.goodsData.orderGoodsId),
          goodsId: parseInt(this.goodsData.goodsId),
          gradeId: parseInt(this.goodsData.gradeId),
          courseId: this.activeSection.courseId,
          moduleId: this.activeSection.moduleId,
          chapterId: this.activeSection.chapterId,
          sectionId: this.activeSection.sectionId,
          fromPlat: 2, //来源平台 1小程序 2网站
          photo: imgUrl || "",
          studyDuration: parseInt(PlayDuration > 0 ? PlayDuration : 0),
          videoCurrentTime: parseInt(currentTime > 0 ? currentTime : 0),
          erJianErZao: this.goodsData.erJianErZao
        };

        if (imgUrl) {
          data.similarity = compareFaceData; // 相似度
        }
        if (status > 0) {
          data.status = status;
        }
        // /study/record 学习记录
        this.$request
          .studyRecord(data)
          .then(res => {
            if (status > 0) {
              this.openPhotoStatus = 0;
              this.$message.success("学习完成");
              this.$bus.$emit("BackVideoFunc", this.activeSection);
              resolve(false);
            }
            if (this.openPhotoStatus === 1) {
              this.postStudyRecord(1);
            }
            if (status == 0 && this.openPhotoStatus !== 1) {
              resolve(true);
            }
          })
          .catch(err => {
            if (err.code === 600) {
              polyvPlayerContext.j2s_pauseVideo();
              this.failToRegister = true; //报名推送不通过
              this.$confirm(`开通信息推送不成功，无法学习！`, "提示", {
                confirmButtonText: "确定",
                closeOnClickModal: false,
                closeOnPressEscape: false,
                distinguishCancelAndClose: false,
                showCancelButton: false,
                showClose: false
              })
                .then(_ => {
                  //停止执行-退出页面
                  this.$router.back(-1);
                })
                .catch(_ => {
                  //停止执行-退出页面
                  this.$router.back(-1);
                });
            } else if (err.code === 559) {
              console.log("拍照不够触发");
              this.$message.error(err.msg);
              this.openPhotoStatus = 1;
              setTimeout(() => {
                this.openPhoto();
              }, 1500);
            } else if (err.code === 558) {
              this.$refs.countDown.openBoxs(parseInt(err.msg.split(",")[1]));
            } else {
              this.$message.error(err.msg || "未知错误");
            }
          });
      });
    },
    //人脸校验
    faceRecognition(url) {
      return new Promise(resolve => {
        this.$request
          .faceCertificationCompareFace({
            imageA: url,
            orderGoodsId: this.goodsData.orderGoodsId,
            gradeId: this.goodsData.gradeId
          })
          .then(res => {
            resolve(res.data);
          })
          .catch(err => {
            if (err.toString().indexOf("timeout") != -1) {
              err = {
                msg: "拍照超时，请重新拍照"
              };
            }
            this.$message({
              type: "warning",
              message: err.msg
            });
            setTimeout(() => {
              this.openPhoto();
            }, 1500);
          });
      });
    },
    //页面显示隐藏逻辑
    pauseVideo() {
      if (
        this.$refs.takePicture.takePhotoModal ||
        this.$refs.takePicture.photoBadStatus ||
        this.failToRegister ||
        this.videoPauseSetTimeStatus
      ) {
        return;
      }
      let _p = this.player;
      if (document.visibilityState === "hidden") {
        _p && _p.j2s_pauseVideo();
      } else if (
        _p &&
        parseInt(_p.j2s_getCurrentTime()) < _p.j2s_getDuration()
      ) {
        this.player.j2s_resumeVideo();
      }
    }
  },
  beforeDestroy() {
    this.$bus.$off("toPlay");
    clearTimeout(this.videoPauseSetTimeout); //删除暂停计算拍照定时器
    // document.removeEventListener("visibilitychange", this.pauseVideo);
    this.player && this.player.destroy(); //初始化播放器
    this.player &&
      this.player.HTML5.video.removeEventListener("timeupdate", this.timeEvent); //监听器
    this.$msgbox.close();
  }
};
</script>

<style lang="scss" scoped>
#videoCy {
  width: 100%;
  height: 100%;
  background: url() no-repeat center center;
  background-size: contain;
  position: relative;
}

.recordStyle {
  position: absolute;
  bottom: 60px;
  padding: 6px 12px;
  left: 8px;
  background-color: rgba(0, 0, 0, 0.4);
  color: #fff;
  border-radius: 24px;
  user-select: none;

  .videoCurrentTime_style {
    display: inline-block;
    width: 50px;
    text-align: center;
  }
  .btn_sty {
    cursor: pointer;
  }
}
</style>
