<template>
  <div>
    <video id="video" ref="video" :width="width" :height="height" autoplay>
    </video>
    <div v-if="showRecognizeButton" style="position: absolute; width: 400px; text-align: center; margin-top: -50px; color: #232323;">
      <span class="verify-button" @click="snap">开始识别</span>
    </div>
  </div>
</template>

<script>
import { mapState } from "vuex";
import {
  UPYUN_URL,
  FACEPP_API,
  FACEPP_KEY,
  FACEPP_SECRET
} from "../../constants/constants.js";

export default {
  name: "FaceRecognition",
  data() {
    return { hide: true };
  },
  props: {
    width: String,
    height: String,
    showRecognizeButton: Boolean,
    closeCamera: Boolean // optional
  },
  async mounted() {
    this.openCamera();
  },
  watch: {
    closeCamera: function(newValue) {
      if (newValue) {
        console.log("关闭摄像头");
        this.$refs.video.srcObject.getTracks().forEach(function(track) {
          track.stop();
        });
      } else {
        this.openCamera();
      }
    }
  },
  beforeDestroy() {
    this.$refs.video.srcObject.getTracks().forEach(function(track) {
      track.stop();
    });
  },
  methods: {
    async openCamera() {
      const video = this.$refs.video;

      if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        try {
          console.log("启动摄像头");
          const stream = await navigator.mediaDevices.getUserMedia({
            video: { facingMode: "user" }
          });

          video.srcObject = stream;
          video.play();
        } catch (error) {
          console.log(error);
          this.$Message.error("无法启用摄像头");
        }
      } else {
        this.$Message.error("没有找到可用的摄像头");
      }
    },
    // TODO: 定时抓拍
    snap() {
      const video = this.$refs.video;
      video.pause();
      var canvas = document.createElement("canvas");
      canvas.width = 220;
      canvas.height = 165;

      var context = canvas.getContext("2d");
      context.drawImage(video, 0, 0, 220, 165);

      canvas.toBlob(this.uploadToServer);
      video.play();
    },
    async uploadToServer(captureBlob) {
      //保存抓拍照片到又拍云
      var fileName = new Date().getTime() + ".jpg";
      var fileUrl =
        "/capture_photo/" + this.user.identityNumber + "/" + fileName;
      try {
        await this.$upyunhttp.put(fileUrl, captureBlob, {
          headers: {
            "Content-Type": "image/jpeg"
          }
        });
      } catch (e) {
        console.log(e);
        this.$Message.error(e.message);
        return;
      }

      const captureFilePath =
        UPYUN_URL +
        "/capture_photo/" +
        this.user.identityNumber +
        "/" +
        fileName;
      await this.faceCompare(captureFilePath);
    },
    async faceCompare(captureFilePath) {
      const res = await this.$http.get("/api/ecs_core/student/getStudentInfo", {
        params: {
          identityNumber: this.user.identityNumber,
          orgId: this.user.rootOrgId
        }
      });
      const faceToken = res.data.faceToken;
      console.log(faceToken);
      console.log(captureFilePath);

      // TODO: 研究是否有更合适的位置，只使用了一次. 应该由server进行检测
      try {
        const faceCompareRes = await fetch(
          FACEPP_API +
            "/compare?" +
            `api_key=${FACEPP_KEY}&api_secret=${FACEPP_SECRET}&face_token1=${faceToken}&image_url2=${captureFilePath}`,
          {
            method: "post",
            headers: {
              "Content-Type": "application/x-www-form-urlencoded"
            }
          }
        );
        const verifyResult = await faceCompareRes.json();
        console.log("人脸检测结果: ", verifyResult);

        // 告知服务器人脸检测结果
        const params = new URLSearchParams();
        params.append("pass", true);
        params.append("action", "COMPARE");
        await this.$http.post("/api/face_capture", params);

        // TODO: 识别成功、失败的通知或跳转

        let pass = false;
        if (verifyResult.faces2.length > 0) {
          var confidence = verifyResult.confidence;
          var thresholds = verifyResult.thresholds;
          if (confidence && thresholds && confidence > thresholds["1e-4"]) {
            pass = true;
          }
        }
        this.$emit("on-recognize-result", {
          error: null,
          pass,
          faceCount: verifyResult.faces2.length
        });
      } catch (e) {
        console.log(e);
        this.$Message.error(e.message);
        return;
      }
    }
  },
  computed: {
    ...mapState(["user"])
  }
};
</script>

<style scoped>
.verify-button {
  font-size: 16px;
  background-color: #ffcc00;
  display: inline-block;
  padding: 6px 16px;
  border-radius: 6px;
}

.verify-button:hover {
  color: #444444;
  cursor: pointer;
}
</style>
