<script setup>
import {Html5Qrcode, Html5QrcodeScanner, Html5QrcodeScanType, Html5QrcodeSupportedFormats} from "html5-qrcode";

const emit = defineEmits('oSuccess', 'onError')
const slots = useSlots();
// 判断是否有 default 插槽
const hasDefaultSlot = computed(() => !!slots.default);

let isShow = ref(false)
let results = ref(null)

let scanInstance = null
const openQrcode = async () => {
  Html5Qrcode.getCameras()
      .then(devices => {
        if (devices && devices.length) {// 当前环境下能识别出摄像头，并且摄像头的数据可能不止一个
          if (!scanInstance) {
            // reader  放置扫码功能的元素ID
            scanInstance = new Html5Qrcode('qr-reader', {
              formatsToSupport: [
                Html5QrcodeSupportedFormats.QR_CODE,
              ],
            })
          }

          isShow.value = true
          scanInstance.start(
              {facingMode: "environment"},
              {
                focusMode: 'continuous',
                fps: 1, // 可选，每n秒帧扫描一次
                qrbox: { // 扫描的UI框
                  width: 250,
                  height: 250
                },
                videoConstraints: {
                  // width: 375,
                  // height: (window.visualViewport.height - 50),
                  aspectRatio: window.visualViewport.height / window.visualViewport.width,
                  facingMode: "environment",
                }
              },
              (decodedText, decodedResult) => {
                showToast('识别成功')
                // 扫描结果
                results.value = {
                  decodedText,
                  decodedResult
                }
                isShow.value = false
                scanInstance.stop()
                emit('oSuccess', {
                  decodedText,
                  decodedResult
                })
              },
              (errorMessage, error) => {
                emit('onError', {
                  errorMessage,
                  error
                })
              }
          )
        }
      })
      .catch((err) => {
        isShow.value = false
        // 错误信息处理仅供参考，具体情况看输出！！！
        let errorStr = ''
        if (typeof err === "string") {
          errorStr = err
        } else {
          if (err.name === "NotAllowedError")
            errorStr = "您需要授予相机访问权限"
          if (err.name === "NotFoundError") {
            errorStr = "未检测到摄像头"
          }
          if (err.name === "NotSupportedError")
            errorStr = "摄像头访问只支持在安全的上下文中，如https或localhost"
          if (err.name === "NotReadableError") errorStr = "摄像头被占用"
          if (err.name === "OverconstrainedError")
            errorStr = "安装摄像头不合适"
          if (err.name === "StreamApiNotSupportedError")
            errorStr = "此浏览器不支持流API"
        }
        showToast(errorStr)
      })
}
const closeQrcode = () => {
  isShow.value = false
  if (scanInstance) scanInstance.stop()
}


let fileList = ref([])
const uploadImg = () => {
  try {
    window.qrcode.callback = (result) => {
      showToast(result);
    };
    let file = state.fileList[0].file;
    let reader = new FileReader();
    reader.onload = (function () {
      return function (e) {
        window.qrcode.decode(e.target.result);
      };
    })(file);
    reader.readAsDataURL(file);
  } catch (error) {
    console.log(error);
    showToast({
      message: error+"识别失败！",
      duration: 2000,
    });
  }
}

const selectFile = ()=> {
  let odeScanner = new Html5QrcodeScanner(
      "qr-code-file", { fps: 1 , qrbox: { // 扫描的UI框
          width: 250,
          height: 250
        },});
  odeScanner.render((e) => {
    console.log(e)
  });
  console.log(odeScanner, 'odeScanner')
}


onMounted(() => {
  selectFile()
})
onUnmounted(() => {
  if (scanInstance) scanInstance.stop()
})
</script>

<template>
  <div>
    <template v-if="hasDefaultSlot">
      <slot></slot>
    </template>
    <template v-else>
      <van-button @click="openQrcode" size="mini">扫一扫</van-button>
    </template>
    <div v-if="false" class="h-200">
      {{ results }}
    </div>
    <div class="overlay" v-show="isShow">
      <div class="absolute w-full z-30 flex flex-row items-center justify-center p-12">
        <div class="absolute left-12 font-bold" @click="closeQrcode">
          <span class="iconfont icon-left text-white"></span>
        </div>
        <div class="text-base text-[#fff] font-bold">
          扫描二维码
        </div>
      </div>
      <div class="relative qr-reader z-20" id="qr-reader"></div>
      <p class="absolute w-full p-12 text-center bottom-100 z-30 text-sm text-[#fff]">请将二维码对准扫码框中心</p>
      <div id="qr-code-file" class="absolute w-54 h-54 grid place-items-center bottom-40 z-30 rounded-full bg-[#000]/80 text-white left-1/2 -translate-x-1/2">
        <img src="~/assets/img/scan/pic.png" height="32" width="32" alt=""/>
      </div>
    </div>
    <div id="qr-code-file" class="w-54 h-54 grid place-items-center bottom-40 z-30 rounded-full bg-[#000]/80 text-white">
      <img src="~/assets/img/scan/pic.png" height="32" width="32" alt=""/>
    </div>
    <van-uploader
        v-model="fileList"
        :preview-image="false"
        :after-read="uploadImg"
        accept="image/*"
        :multiple="false"
        :max-count="1"
    >
      <van-icon name="photo-o"
      /></van-uploader>
  </div>
</template>

<style scoped lang="scss">
.overlay {
  position: fixed;
  bottom: 0;
  left: 0;
  z-index: 999999;
  width: 100%;
  height: calc(100% - 50px);
  background: rgba(0, 0, 0, 0.7);

  .scan-instruction {

  }
}
</style>