<template>
  <div class="qr-scanner">
    <video ref="videoRef" class="video" playsinline autoplay></video>

    <!-- 遮罩层 -->
    <div class="mask">
      <!-- 中间扫码区域 -->
      <div class="scan-area">
        <div class="corner left-top"></div>
        <div class="corner left-bottom"></div>
        <div class="corner right-top"></div>
        <div class="corner right-bottom"></div>
        <!-- 扫描线动画 -->
        <div class="scan-line" v-if="isScanning"></div>
      </div>
    </div>

    <!-- 顶部提示 -->
    <div class="header">
      <div class="back" @click="$router.back()">
        <van-icon name="arrow-left" />
      </div>
      <div class="title">扫一扫</div>
      <div class="placeholder"></div>
    </div>

    <!-- 底部提示 -->
    <div class="footer">
      <div class="tip" v-if="!isScanning && !result && !error">将二维码放入框内即可自动扫描</div>
      <div class="error" v-if="error">{{ error }}</div>
      <div class="result" v-if="result">
        <div class="label">扫描结果：</div>
        <div class="value">{{ result }}</div>
      </div>
    </div>

    <!-- 开始扫描提示 -->
    <div class="start-tip" v-if="!isScanning && !result" @click="startScan">
      <van-icon name="scan" size="32" />
      <span>点击开始扫描</span>
    </div>

    <!-- 核销确认弹框 -->
    <van-dialog v-model:show="showConfirm" title="确认核销" show-cancel-button @confirm="confirmVerify"
      @cancel="cancelVerify">
      <div style="padding: 20px; text-align: center;">
        是否确认核销此礼品券？<br>
        券码：{{ pendingSysid }}
      </div>
    </van-dialog>
  </div>
</template>

<script>
import { BrowserMultiFormatReader, NotFoundException } from '@zxing/library';

export default {
  name: 'QrReader',
  data() {
    return {
      videoRef: null,
      result: '',
      isScanning: false,
      error: '',
      codeReader: null,
      stream: null,
      showConfirm: false,
      pendingSysid: '',
    }
  },
  mounted() {
    this.videoRef = this.$refs.videoRef;
  },
  beforeUnmount() {
    this.stopScan();
  },
  methods: {
    async startScan() {
      this.error = '';
      this.result = '';

      try {
        this.codeReader = new BrowserMultiFormatReader();

        await this.codeReader.decodeFromVideoDevice(
          null,
          this.videoRef,
          (decodedText, err) => {
            if (decodedText) {
              this.result = decodedText;
              this.handleScanResult(decodedText);
              this.stopScan();
            }
            if (err && !(err instanceof NotFoundException)) {
              console.error('扫码错误:', err);
            }
          }
        );

        this.isScanning = true;
      } catch (e) {
        console.error(e);
        if (e.name === 'NotAllowedError' || e.name === 'PermissionDeniedError') {
          this.error = '摄像头权限被拒绝，请在设置中允许访问摄像头';
        } else if (e.name === 'NotFoundError' || e.name === 'DevicesNotFoundError') {
          this.error = '未找到摄像头设备';
        } else {
          this.error = e.message || '无法访问摄像头，请确保已授予摄像头权限';
        }
      }
    },
    stopScan() {
      if (this.codeReader) {
        this.codeReader.reset();
      }
      this.isScanning = false;
    },
    handleScanResult(text) {
      const str = String(text);
      // 如果是商家收款码链接，直接跳转
      if (str.includes('/Checkout?id=')) {
        const id = str.split('/Checkout?id=')[1];
        window.location.href = `#/Checkout?id=${id}`;
        return;
      }
      // 如果是礼品券核销链接
      const match = str.match(/DUserlipinquansClient\/([^/]+)\/state/);
      if (match) {
        this.pendingSysid = match[1];
        this.showConfirm = true;
        return;
      }
      // 如果是http链接，直接跳转
      if (str.startsWith('http://') || str.startsWith('https://')) {
        window.location.href = str;
        return;
      }
      // 其他内容显示结果
      this.result = str;
    },
    confirmVerify() {
      this.showConfirm = false;
      this.$put(`/v1/client/DUserlipinquansClient/${this.pendingSysid}/state`).then(res => {
        if (res.status === 200) {
          this.$showSuccessToast('核销成功');
          this.result = '核销成功';
          this.$navigate('CertificateRecord?type=verif')
          // setTimeout(() => {
          //   this.$router.back();
          // }, 1500);
        }
      }).catch(err => {
        this.$showFailToast(err.message || '核销失败');
        this.error = err.message || '核销失败';
      });
    },
    cancelVerify() {
      this.showConfirm = false;
      this.pendingSysid = '';
    },
  },
}
</script>

<style scoped>
.qr-scanner {
  position: fixed;
  inset: 0;
  background: #000;
  z-index: 1000;
}

.video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.mask {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
}

.scan-area {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 60vw;
  height: 60vw;
  max-width: 250px;
  max-height: 250px;
  background: transparent;
}

.scan-area::before {
  content: '';
  position: absolute;
  inset: 0;
  background: transparent;
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.5);
}

.corner {
  position: absolute;
  width: 24px;
  height: 24px;
  border-color: #fff;
  border-style: solid;
}

.left-top {
  top: 0;
  left: 0;
  border-width: 3px 0 0 3px;
  border-radius: 4px 0 0 0;
}

.left-bottom {
  bottom: 0;
  left: 0;
  border-width: 0 0 3px 3px;
  border-radius: 0 0 0 4px;
}

.right-top {
  top: 0;
  right: 0;
  border-width: 3px 3px 0 0;
  border-radius: 0 4px 0 0;
}

.right-bottom {
  bottom: 0;
  right: 0;
  border-width: 0 3px 3px 0;
  border-radius: 0 0 4px 0;
}

.scan-line {
  position: absolute;
  top: 0;
  left: 10%;
  right: 10%;
  height: 2px;
  background: linear-gradient(90deg, transparent, #07c160, transparent);
  animation: scanMove 2s linear infinite;
}

@keyframes scanMove {
  0% {
    top: 0;
  }

  100% {
    top: 100%;
  }
}

.header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  padding-top: calc(12px + env(safe-area-inset-top));
  background: rgba(0, 0, 0, 0.3);
}

.back {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 20px;
}

.title {
  color: #fff;
  font-size: 17px;
  font-weight: 500;
}

.placeholder {
  width: 32px;
}

.footer {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 20px;
  padding-bottom: calc(20px + env(safe-area-inset-bottom));
  text-align: center;
}

.tip {
  color: #fff;
  font-size: 14px;
  text-align: center;
}

.error {
  color: #ff4d4f;
  font-size: 14px;
  text-align: center;
  margin-top: 8px;
}

.result {
  background: rgba(255, 255, 255, 0.9);
  border-radius: 8px;
  padding: 12px;
  margin-bottom: 16px;
}

.result .label {
  font-size: 14px;
  color: #666;
  margin-bottom: 4px;
}

.result .value {
  font-size: 16px;
  color: #333;
  word-break: break-all;
}

.controls {
  position: absolute;
  bottom: 100px;
  left: 50%;
  transform: translateX(-50%);
}

.start-tip {
  position: absolute;
  bottom: 120px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  color: #fff;
  font-size: 14px;
}
</style>