<template>
  <div class="page">
    <div class="bottom">
      <!-- 人物框 -->
      <!-- <image
        v-if="!isSuccess"
        class="frameImg"
        src="../../assets/img/people.png"
        mode="scaleToFill"
      /> -->
      <video
        v-if="!isSuccess"
        id="video"
        muted
        autoplay="autoplay"
        :controls="false"
        :enable-progress-gesture="false"
      ></video>
      <div v-if="!isSuccess">
        <div class="selectImg" @click="uploadImg">
          <img src="../../assets/img/selectImg.png" />
          <div class="uploadText">上传照片</div>
        </div>
        <div id="action" @click="takePicture">
          <view v-show="showTakeTips" class="takeTips1">请把脸面向摄像头</view>
          <view v-show="showTakeTips" class="takeTips2"
            >点击三秒后开始拍照
          </view>
          <div class="circleInside"></div>
        </div>
      </div>

      <div v-if="isSuccess">
        <div class="selectImg" @click="uploadImg">
          <img src="../../assets/img/selectImg.png" />
          <div class="uploadText">上传照片</div>
        </div>

        <div class="confirm" @click="confirmPhoto">
          <!-- <img src="../../assets/img/success.png" /> -->
          <div class="sure">确定</div>

          <div class="uploadText">
            就这张了 <img src="../../assets/img/success.png" />
          </div>
        </div>

        <div class="reTry" @click="reTry">
          <img src="../../assets/img/reTry.png" />
          <div class="uploadText">重新拍摄</div>
        </div>
      </div>

      <canvas
        v-if="isShowCanvas"
        id="canvas"
        style="width: 1530; height: 950"
      ></canvas>

      <div v-if="isSuccess" class="preview">
        <img v-if="!isUpload" class="fromCamera" :src="CimgSrc" />
        <img v-if="isUpload" class="fromUpload" :src="UimgSrc" />
      </div>
    </div>

    <div class="top">
      <div class="example">
        <img src="../../assets/img/c867236efb4fc5707257ef8daf26db4.png" />
      </div>
      <div class="model" @click="goSelectModel">
        <img :src="modelUrl" alt="" />
        <div class="reSelect">点击重新选择模板</div>
      </div>
    </div>
    <!-- Top section -->
    <u-overlay class="overlay" :show="showQrCode" opacity="0.9">
      <view class="content">
        <view class="imageBox">
          <image :src="QRCodeUrl" mode="scaleToFill" />
        </view>
        <text>打开微信扫码上传照片</text>
        <view class="orangeBtn" style="margin-top: 100rpx" @click="cancelUplaod"
          >取&nbsp;消</view
        >
      </view>
    </u-overlay>
  </div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import { BASE_URL } from "../../utils/request";
import { onLoad, onShow, onUnload } from "@dcloudio/uni-app";

import { getImageQrcode, findImage } from "../../api/camera.js";

let CimgSrc = ref(""); // 相机拍照的图片路径，上传前需校验
let CimgSrcYASUO = ref(""); // 压缩后的图片
let UimgSrc = ref(""); // 用户上传的图片路径，上传无需校验
let isSuccess = ref(false);
let isShowCanvas = ref(true);
let isUpload = ref(false);

let modelUrl = ref("");
let modelId = ref("");
let modelMouldType = ref("");

let QRCodeUrl = ref("");
let showQrCode = ref(false);

let timer = ref(null);
const getView = () => {
  uni.getSystemInfo({
    success: (res) => {
      const viewportWidth = res.windowWidth; // 视口宽度
      const viewportHeight = res.windowHeight; // 视口高度
      alert(viewportWidth);
      alert(viewportHeight);
    },
  });
};

const showTakeTips = ref(true);

const startCamera = () => {
  function getUserMedia(constraints, success, error) {
    if (navigator.mediaDevices.getUserMedia) {
      //最新的标准API
      navigator.mediaDevices
        .getUserMedia({
          audio: false,
          video: {
            facingMode: "user",
            // width: 1000,
            // height: 1000,
            width: 1080,
            height: 1305,
            // width: 2100,
            // height: 2100,
          },
        })
        .then(success)
        .catch(error);
    } else if (navigator.webkitGetUserMedia) {
      //webkit核心浏览器
      navigator.webkitGetUserMedia(constraints, success, error);
    } else if (navigator.mozGetUserMedia) {
      //firfox浏览器
      navigator.mozGetUserMedia(constraints, success, error);
    } else if (navigator.getUserMedia) {
      //旧版API
      navigator.getUserMedia(constraints, success, error);
    }
  }

  const video = document.querySelector("video.uni-video-video");
  // video.style.transform = "scaleX(-1)";
  // video.style.transform = "rotateY(180deg)"; //镜像
  let canvas = document.querySelector("canvas.uni-canvas-canvas");
  const action = document.querySelector("#action");
  let context = canvas.getContext("2d");

  function success(stream) {
    //兼容webkit核心浏览器
    let CompatibleURL = window.URL || window.webkitURL;
    //将视频流设置为video元素的源
    console.log(stream);

    //video.src = CompatibleURL.createObjectURL(stream);
    video.srcObject = stream;
    video.play();
  }

  function error(error) {
    console.log(`访问用户媒体设备失败${error.name}, ${error.message}`);
  }

  if (
    navigator.mediaDevices.getUserMedia ||
    navigator.getUserMedia ||
    navigator.webkitGetUserMedia ||
    navigator.mozGetUserMedia
  ) {
    //调用用户媒体设备, 访问摄像头
    getUserMedia(
      {
        audio: false,
        video: {
          facingMode: "user",
          // width: 240,
          // height: 450,
          width: 1080,
          height: 1305,
          // width: 2100,
          // height: 2100,
        },
      },
      success,
      error
    );
  } else {
    alert("不支持访问用户媒体");
  }

  action.addEventListener("click", function () {
    showTakeTips.value = false;
    uni.showToast({
      title: "准备开始拍照",
      icon: "success",
    });
    setTimeout(() => {
      let i = 3;
      const timer = setInterval(() => {
        uni.showLoading({
          title: i,
        });
        i--;
        console.log(i);
        if (i == 0) {
          clearInterval(timer);

          setTimeout(async () => {
            uni.hideLoading();
            // canvas.width = 1530;
            // canvas.height = 950;
            canvas.width = 1500;
            canvas.height = 1500;
            context.drawImage(video, 0, 0);
            let dataURL = canvas.toDataURL("image/png");
            // console.log(dataURL);
            CimgSrc.value = dataURL;
            UimgSrc.value = "";

            setTimeout(() => {
              isShowCanvas.value = false;
              isSuccess.value = true;
              showTakeTips.value = true;
            }, 10);
          }, 1000);
        }
      }, 1100);
    }, 1000);
  });

  // 备用方案
  // action.addEventListener("click", function () {
  //   context.drawImage(video, -50, -50, 310, 220);
  //   const dataURL = canvas.toDataURL("image/png");
  //   imgSrc.value = dataURL;

  //   setTimeout(() => {
  //     isShowCanvas.value = false;
  //     isSuccess.value = true;
  //   }, 10);
  //   console.log(dataURL);
  // });
};
//压缩图片
function compressBase64Image(base64String, maxWidth, maxHeight) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.src = base64String;

    img.onload = function () {
      const canvas = document.createElement("canvas");
      let width = img.width;
      let height = img.height;

      if (width > maxWidth) {
        height *= maxWidth / width;
        width = maxWidth;
      }

      if (height > maxHeight) {
        width *= maxHeight / height;
        height = maxHeight;
      }

      const ctx = canvas.getContext("2d");
      canvas.width = width;
      canvas.height = height;
      ctx.drawImage(img, 0, 0, width, height);

      const compressedBase64 = canvas.toDataURL("image/jpeg");
      resolve(compressedBase64);
    };

    img.onerror = function (error) {
      reject(error);
    };
  });
}

const takePicture = () => {
  console.log("Take Picture !");
};

const goSelectModel = () => {
  uni.navigateTo({
    url: `/pages/chooseStyle/index`,
  });
};

// 确认照片
const confirmPhoto = () => {
  // alert("点击确定");
  // alert(UimgSrc.value, "UimgSrc.value");
  // alert(CimgSrc.value, "CimgSrc.value");
  try {
    if (UimgSrc.value) {
      uni.navigateTo({
        url: `/pages/createing/index?imageUrl=${UimgSrc.value}&id=${modelId.value}`,
      });
    } else if (CimgSrc.value) {
      // 本地存储中的拍照照片
      // alert(uni.getStorageSync("CcurrentUrl"), "CcurrentUrl");
      // // let CimageUrl = uni.getStorageSync("CcurrentUrl");
      // // 用户上一次使用相机拍照的照片，从本地回显，已通过校验，直接放行
      if (uni.getStorageSync("CcurrentUrl")) {
        uni.navigateTo({
          url: `/pages/createing/index?imageUrl=${CimgSrc.value}&id=${modelId.value}`,
        });
        //   // 用户使用相机拍照的照片，未校验，走完校验流程放行
      } else {
        dealImage(CimgSrc.value);
      }
      // dealImage(CimgSrcYASUO.value);
    }
  } catch (e) {
    uni.showToast({
      title: e,
      icon: "success",
      mask: true,
    });
  }
  // 用户上传的照片，已通过校验，直接放行
};

const dealImage = async (imageUrl) => {
  try {
    uni.showLoading({
      title: "上传中，马上就好",
    });
    await compressBase64Image(imageUrl, 1200, 1200)
      .then((compressedBase64) => {
        CimgSrcYASUO.value = compressedBase64;
      })
      .catch((error) => {
        console.error("压缩失败", error);
      });
    // 将二进制数据转换为 Blob 对象
    // let blob = await dataURLtoBlob(imageUrl);
    // checkImageByBaidu(blob);
    // let blob = await dataURLtoBlob(imageUrl);
    // console.log(dataURLtoBlob(imageUrl));
    checkImageByBaidu(dataURLtoBlob(CimgSrcYASUO.value));
  } catch (error) {
    console.error("压缩失败", error);
  }
};

/**
 * Base64字符串转二进制流
 * @param {String} dataurl Base64字符串(字符串包含Data URI scheme，例如：data:image/png;base64, )
 */
const dataURLtoBlob = (dataurl) => {
  var arr = dataurl.split(","),
    mime = arr[0].match(/:(.*?);/)[1],
    bstr = atob(arr[1]),
    n = bstr.length,
    u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], {
    type: mime,
  });
};

// 百度图片校验
const checkImageByBaidu = async (file) => {
  try {
    uni.showLoading({
      title: "正在检测图片合法性 1/3",
    });
    uni.uploadFile({
      url: BASE_URL + "api/baidu/checkPhoto",
      file,
      header: {
        authorization: uni.getStorageSync("token"),
      },
      timeout: 30000,
      // formData: data,
      success: (res) => {
        console.log(res, "上传成功");
        const data = JSON.parse(res.data);
        if (data.code == 200) {
          uni.hideLoading();
          checkImageByMetavatar(file);
        } else {
          uni.hideLoading();
          uni.showToast({
            title: "图片不合规哦，请更换一张",
            icon: "error",
          });
        }
      },
      fail: (res) => {
        uni.hideLoading();
        uni.showToast({
          title: "上传失败，请稍后再试",
          icon: "none",
        });
        console.log(res, "上传失败");
      },
    });
  } catch (error) {
    uni.hideLoading();
    uni.showToast({
      title: "请求失败，请稍后再试",
      icon: "none",
    });
  }
};

// 邃芒人脸校验
const checkImageByMetavatar = async (file) => {
  uni.showLoading({
    title: "正在检测人脸位置 2/3",
  });
  uni.uploadFile({
    url: BASE_URL + "api/userDigital/checkPhoto",
    file,
    header: {
      authorization: uni.getStorageSync("token"),
    },
    timeout: 30000,
    // formData: data,
    success: (res) => {
      console.log(res, "上传成功");
      const data = JSON.parse(res.data);
      if (data.code == 200) {
        uni.hideLoading();
        uoloadImageAws(file);
      } else {
        uni.hideLoading();
        uni.showToast({
          title: "请参考提示区域调整站位哦",
          icon: "error",
        });
      }
    },
    fail: (res) => {
      uni.hideLoading();
      uni.showToast({
        title: "上传失败，请稍后再试",
        icon: "none",
      });
      console.log(res, "上传失败");
    },
  });
};

// 上传图片到服务器（两步校验通过后）
const uoloadImageAws = async (file) => {
  uni.showLoading({
    title: "检测完成，上传中 3/3",
  });
  uni.uploadFile({
    url: BASE_URL + "api/upload/awsImgUpload",
    file,
    header: {
      authorization: uni.getStorageSync("token"),
    },
    timeout: 30000,
    // formData: data,
    success: (res) => {
      console.log(res, "上传成功");
      uni.hideLoading();
      const data = JSON.parse(res.data);
      if (data.code == 200) {
        uni.showToast({
          title: "上传成功！",
          icon: "success",
          duration: 1500,
        });
        setTimeout(() => {
          // 将拍照照片地址存储到本地并清空上传照片地址
          // uni.setStorageSync("CcurrentUrl", data.data.url);
          uni.setStorageSync("CcurrentUrl", data.data.url);
          uni.setStorageSync("UcurrentUrl", null);
          uni.navigateTo({
            url: `/pages/createing/index?imageUrl=${data.data.url}&id=${modelId.value}`,
          });
        }, 1000);
      } else {
        uni.hideLoading();
        uni.showToast({
          title: "网络波动，请稍后再试",
          icon: "error",
        });
      }
    },
    fail: (res) => {
      uni.hideLoading();
      uni.showToast({
        title: "上传失败，请稍后再试",
        icon: "none",
      });
      console.log(res, "上传失败");
    },
  });
};

// 不满意，重新拍一张
const reTry = () => {
  isSuccess.value = false;
  isUpload.value = false;
  isShowCanvas.value = true;
  CimgSrc.value = "";
  UimgSrc.value = "";
  CimgSrcYASUO.value = "";
  uni.setStorageSync("CcurrentUrl", null);
  setTimeout(() => {
    startCamera();
  }, 10);
};

// 点击上传照片按钮
const uploadImg = async () => {
  const data = {
    machineQrcodeId: localStorage.getItem("UserId"),
    mouldType: modelMouldType.value,
  };
  // const UserId = localStorage.getItem("UserId");
  // const mouldType = modelMouldType.value;
  try {
    const res = await getImageQrcode(data);
    QRCodeUrl.value = res.data.wxQrcode;
    showQrCode.value = true;

    // 成功展示二维码之后，轮询获取上传照片状态
    timer.value = setInterval(() => {
      refreshUploadStatus(res.data.id);
    }, 1000);
    console.log(res, "res");
  } catch (error) {
    console.log(error, "error");
  }
};

// 刷新状态，直到返回用户上传的图片url
const refreshUploadStatus = async (id) => {
  try {
    const res = await findImage(id);
    console.log(res, "res");
    if (res.data.imageList && res.data.imageList.length) {
      const imageUrl = res.data.imageList[0];
      clearInterval(timer.value);
      uni.showToast({
        title: "上传成功！",
        icon: "success",
      });
      showQrCode.value = false;
      UimgSrc.value = imageUrl;
      CimgSrc.value = "";
      CimgSrcYASUO.value = "";
      isShowCanvas.value = false;
      isSuccess.value = true;
      isUpload.value = true;

      // 将上传照片地址存储到本地并清空拍照照片地址
      uni.setStorageSync("CcurrentUrl", null);
      uni.setStorageSync("UcurrentUrl", UimgSrc.value);
    }
  } catch (error) {
    console.log(error, "error");
  }
};

// 点击取消，关闭二维码弹窗并取消轮询
const cancelUplaod = () => {
  showQrCode.value = false;
  clearInterval(timer.value);
};

onLoad((options) => {
  console.log(options, "options");
  modelUrl.value = options.modelUrl;
  modelId.value = options.id;
  modelMouldType.value = options.mouldType;
});

onMounted(() => {
  clearInterval(timer.value);
  startCamera();
  const CimageUrl = uni.getStorageSync("CcurrentUrl");
  const UimageUrl = uni.getStorageSync("UcurrentUrl");
  if (CimageUrl || UimageUrl) {
    setTimeout(async () => {
      showQrCode.value = false;
      if (CimageUrl) {
        UimgSrc.value = "";
        CimgSrc.value = CimageUrl;
        isUpload.value = false;
      } else if (UimageUrl) {
        UimgSrc.value = UimageUrl;
        CimgSrc.value = "";
        CimgSrcYASUO.value = "";
        isUpload.value = true;
      }

      isShowCanvas.value = false;
      isSuccess.value = true;
    }, 1000);
  }
});

//#region 页面初始化和卸载
const resetTimer = ref(null);
onMounted(() => {
  window.document.addEventListener("touchstart", () => {
    // 用户点击时，清除之前的定时器
    clearTimeout(resetTimer.value);
    // 重新设定120秒后触发的定时器
    resetTimer.value = setTimeout(() => {
      userInfoModulesPinia.clearStorage();
      window.webview.raiseEvent("pageRefresh", "test_params");
      uni.redirectTo({ url: "/pages/login/index" });
    }, 300000);
  });
  resetTimer.value = setTimeout(() => {
    userInfoModulesPinia.clearStorage();
    window.webview.raiseEvent("pageRefresh", "test_params");
    uni.redirectTo({ url: "/pages/login/index" });
  }, 300000);
});
onUnload(() => {
  uni.hideLoading();
  clearTimeout(resetTimer.value);
});
//#endregion -----------------------
</script>

<style lang="scss" scoped>
:deep(.uni-toast) {
  width: 300rpx;
  font-size: 50rpx;
  font-weight: 900;
  padding: 20rpx 30rpx;
  color: #ff4f00;

  .uni-toast__icon {
    width: 50rpx !important;
    height: 50rpx !important;
  }
}
.page {
  width: 100vw;
  height: 100vh;
  padding: 0;

  .top {
    display: flex;
    width: 100%;
    height: 32%;
    .example {
      width: 60%;
      height: 100%;
      color: #000;
      background-color: #fff;
      img {
        width: 100%;
        height: 100%;
      }
    }
    .model {
      position: relative;
      width: 40%;
      height: 100%;
      background-color: #000000;
      img {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 100%;
        height: 100%;
      }
      .reSelect {
        position: absolute;
        width: 250rpx;
        left: 50%;
        bottom: 10rpx;
        text-align: center;
        transform: translateX(-50%);
      }
    }
  }
  .bottom {
    position: relative;
    width: 100%;
    height: 68%;
    overflow: hidden;
    .frameImg {
      position: absolute;
      top: 40%;
      left: 50%;
      transform: translate(-50%, -50%);
      width: 60%;
      height: 40%;
      z-index: 3;
    }
    video {
      width: 100%;
      height: 100%;
      // width: 1080px;
      // height: 1305px;
      :deep(.uni-video-video) {
        position: absolute;
        left: 0;
        top: -50px;
        width: 100% !important;
        height: 720px !important;
      }
    }
    .selectImg {
      position: absolute;
      left: 65rpx;
      bottom: 75rpx;
      width: 68rpx;
      height: 68rpx;
      border: 5rpx solid #ffffff;
      border-radius: 5rpx;
      z-index: 99;
      img {
        position: absolute;
        left: 50%;
        bottom: 50%;
        transform: translate(-50%, 50%);
        width: 70%;
        height: 70%;
      }
      .uploadText {
        position: absolute;
        left: 50%;
        bottom: -40rpx;
        width: 150%;
        font-size: 20rpx;
        transform: translateX(-40%);
      }
    }

    #action {
      position: absolute;
      left: 50%;
      bottom: 45rpx;
      width: 120rpx;
      height: 120rpx;
      transform: translateX(-50%);
      background-color: #ffffff;
      border-radius: 60rpx;
      z-index: 99;
      .takeTips1 {
        position: absolute;
        width: 300rpx;
        top: -70rpx;
        left: 50%;
        transform: translateX(-50%);
        text-align: center;
        color: #ff4f00;
      }
      .takeTips2 {
        position: absolute;
        width: 300rpx;
        top: -40rpx;
        left: 50%;
        transform: translateX(-50%);
        text-align: center;
        color: #ff4f00;
      }
      .circleInside {
        position: absolute;
        left: 50%;
        bottom: 50%;
        transform: translate(-50%, 50%);
        width: 100rpx;
        height: 100rpx;
        background-color: #ffffff;
        border-radius: 50%;
        border: 6rpx solid #000;
      }
    }

    .confirm {
      position: absolute;
      left: 50%;
      bottom: 75rpx;
      width: 180rpx;
      height: 80rpx;
      // border: 5rpx solid #ffffff;
      transform: translateX(-50%);
      border-radius: 60rpx;
      z-index: 9999999;
      img {
        // position: absolute;
        // left: 50%;
        // bottom: 50%;
        // transform: translate(-50%, 50%);
        width: 100%;
        height: 100%;
        width: 30rpx;
        height: 30rpx;
        vertical-align: text-top;
      }
      .sure {
        margin-top: 30rpx;
        text-align: center;
        width: 100%;
        height: 50rpx;
        line-height: 50rpx;
        background-color: #2ba245;
        border-radius: 15rpx;
      }
      .uploadText {
        // position: absolute;
        // left: 50%;
        // bottom: -40rpx;
        // width: 150%;

        width: 100%;
        height: 30rpx;
        line-height: 30rpx;
        font-size: 20rpx;
        // transform: translateX(-32%);
        text-align: center;
      }
    }

    .reTry {
      position: absolute;
      right: 65rpx;
      bottom: 75rpx;
      width: 68rpx;
      height: 68rpx;
      border: 5rpx solid #ffffff;
      border-radius: 5rpx;
      z-index: 99;
      img {
        position: absolute;
        left: 50%;
        bottom: 50%;
        transform: translate(-50%, 50%);
        width: 70%;
        height: 70%;
      }
      .uploadText {
        position: absolute;
        left: 50%;
        bottom: -40rpx;
        width: 150%;
        font-size: 20rpx;
        transform: translateX(-40%);
      }
    }

    .preview {
      position: relative;
      width: 100%;
      height: 100%;
      z-index: 1;
      .fromCamera {
        // position: absolute;
        // top: 110rpx;
        // left: 130rpx;
        width: 100%;
      }
      .fromUpload {
        position: absolute;
        top: 110rpx;
        left: 50%;
        transform: translateX(-50%);
        width: 45%;
      }
    }
  }
  .overlay {
    .content {
      width: 100%;
      height: 100vh;
      display: flex;
      flex-direction: column;
      align-items: center;
      text-align: center;
      .imageBox {
        position: relative;
        margin-top: 200rpx;
        width: 300rpx;
        height: 300rpx;
        border-radius: 30rpx;
        background-color: #fff;
        .mask {
          position: absolute;
          width: 100%;
          height: 100%;
          border-radius: 30rpx;
          background-color: rgba($color: #000000, $alpha: 0.7);
          z-index: 2;
        }
        image {
          width: 100%;
          height: 100%;
          border-radius: 30rpx;
          background-color: #fff;
        }
      }
      text {
        margin-top: 20rpx;
        font-weight: 900;
        font-size: 32rpx;
      }
      // .orangeBtn {
      //   margin-top: 100rpx;
      // }
    }
  }
}
</style>
