<template>
  <div class="qr-scanner-container">
    <div id="qr-reader" class="scanner-box"></div>

    <div v-if="errorMsg" class="error-msg">{{ errorMsg }}</div>

    <div class="focus-tip" v-if="!errorMsg && !isPaused">
      <div class="scan-line"></div>
      <div class="scan-text">将条码置于镜头范围内即可</div>
    </div>

    <div class="focus-tip success" v-if="isPaused">
      <div class="scan-text-success">
        <el-icon><CircleCheckFilled /></el-icon>
        扫描成功，3秒后继续...
      </div>
    </div>

    <div v-if="hasZoom" class="zoom-control">
      <span class="zoom-icon">-</span>
      <input
          type="range"
          :min="zoomMin"
          :max="zoomMax"
          step="0.1"
          v-model="currentZoom"
          @input="handleZoom"
      />
      <span class="zoom-icon">+</span>
      <div class="zoom-value">{{ currentZoom }}x</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue'
import { Html5Qrcode, Html5QrcodeSupportedFormats } from 'html5-qrcode'
import { CircleCheckFilled } from '@element-plus/icons-vue'

const emit = defineEmits(['decode', 'error'])

const errorMsg = ref('')
const isPaused = ref(false)
let html5QrCode: Html5Qrcode | null = null
const scannerElementId = "qr-reader"

// 变焦控制状态
const hasZoom = ref(false)
const zoomMin = ref(1)
const zoomMax = ref(5)
const currentZoom = ref(1)

const startScanning = async () => {
  try {
    html5QrCode = new Html5Qrcode(scannerElementId, {
      useBarCodeDetectorIfSupported: true,
      formatsToSupport: [
        Html5QrcodeSupportedFormats.CODE_128,
        Html5QrcodeSupportedFormats.QR_CODE
      ],
      verbose: false
    })

    const config = {
      fps: 20,
      // ★★★ 核心修改点 2：移除了 qrbox 属性 ★★★
      // 移除后，库默认会对每一帧的“全画面”进行解析，不再局限于中间区域
      // qrbox: { width: 300, height: 100 },

      disableFlip: false,
      videoConstraints: {
        facingMode: "environment",
        // 保持高分辨率以支持微小条码
        width: { min: 1280, ideal: 3840, max: 3840 },
        height: { min: 720, ideal: 2160, max: 2160 },
        focusMode: "continuous",
        advanced: [{ focusMode: "macro" }, { zoom: 2.0 }]
      }
    }

    await html5QrCode.start(
        { facingMode: "environment" },
        config,
        (decodedText) => {
          if (isPaused.value) return
          console.log(`Scan: ${decodedText}`)
          isPaused.value = true
          emit('decode', decodedText)

          if (navigator.vibrate) navigator.vibrate(200);

          setTimeout(() => {
            isPaused.value = false
          }, 3000)
        },
        (errorMessage) => {
          // ignore
        }
    )

    checkZoomCapability()

  } catch (err: any) {
    let msg = '无法启动摄像头'
    console.error("Scanner Error:", err)
    errorMsg.value = msg
    emit('error', msg)
  }
}

// 检测硬件变焦能力
const checkZoomCapability = () => {
  if (!html5QrCode) return

  try {
    const videoTrack = html5QrCode.getRunningTrackCameraCapabilities() as MediaTrackCapabilities;

    // @ts-ignore
    if (videoTrack && 'zoom' in videoTrack) {
      hasZoom.value = true
      // @ts-ignore
      zoomMin.value = videoTrack.zoom.min || 1
      // @ts-ignore
      zoomMax.value = videoTrack.zoom.max || 5
      // @ts-ignore
      currentZoom.value = videoTrack.zoom.min || 1
    }
  } catch (e) {
    console.warn("无法获取变焦能力", e)
  }
}

// 处理滑块拖动
const handleZoom = () => {
  if (!html5QrCode) return

  try {
    html5QrCode.applyVideoConstraints({
      advanced: [{ zoom: Number(currentZoom.value) }]
    })
  } catch (e) {
    console.error("变焦失败", e)
  }
}

const stopScanning = async () => {
  if (html5QrCode) {
    try {
      if (html5QrCode.isScanning) {
        await html5QrCode.stop()
      }
      html5QrCode.clear()
    } catch (e) {
      console.error("Stop failed", e)
    }
  }
}

onMounted(() => {
  setTimeout(() => {
    startScanning()
  }, 500)
})

onUnmounted(() => {
  stopScanning()
})
</script>

<style scoped>
.qr-scanner-container {
  width: 100%;
  height: 100%;
  position: relative;
  background-color: #000;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  /* 如果是全屏模式，这里不需要圆角，或者保持圆角视你的UI设计而定 */
  border-radius: 0;
}

.scanner-box {
  width: 100%;
  height: 100%;
}

:deep(#qr-reader) {
  width: 100%;
  height: 100%;
  border: none !important;
  padding: 0 !important;
}

:deep(#qr-reader video) {
  width: 100% !important;
  height: 100% !important;
  object-fit: cover !important;
  display: block !important;
}

.error-msg {
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  text-align: center;
  color: #fff;
  background: rgba(245, 108, 108, 0.85);
  padding: 15px;
  transform: translateY(-50%);
  z-index: 20;
}

/* --- ★ 修改点 3：视觉层 CSS 更新 --- */
.focus-tip {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  /* 移除了 border 和 box-shadow，不再显示红框和黑色遮罩 */
  pointer-events: none;
  z-index: 10;
  display: flex;
  justify-content: center;
  align-items: center;
}

.focus-tip.success {
  background: rgba(103, 194, 58, 0.2); /* 成功时全屏微微泛绿 */
}

/* 扫描线改为全屏宽度 */
.scan-line {
  width: 100%;
  height: 2px;
  background: rgba(255, 0, 0, 0.5);
  box-shadow: 0 0 4px rgba(255, 0, 0, 0.8);
  position: absolute;
  /* 动画范围从 10% 到 90% */
  animation: scan-move 2.5s infinite linear;
}

.scan-text {
  position: absolute;
  bottom: 150px; /* 调整文字位置 */
  color: rgba(255, 255, 255, 0.8);
  font-size: 14px;
  text-shadow: 0 1px 3px rgba(0,0,0,0.8);
  background: rgba(0,0,0,0.3);
  padding: 4px 10px;
  border-radius: 4px;
}

.scan-text-success {
  color: #fff;
  font-size: 20px;
  font-weight: bold;
  display: flex;
  align-items: center;
  gap: 10px;
  text-shadow: 0 2px 4px rgba(0,0,0,0.8);
  background: rgba(103, 194, 58, 0.9);
  padding: 15px 30px;
  border-radius: 50px;
}

@keyframes scan-move {
  0% { top: 0%; opacity: 0; }
  10% { opacity: 1; }
  90% { opacity: 1; }
  100% { top: 100%; opacity: 0; }
}

/* 变焦控制器 */
.zoom-control {
  position: absolute;
  bottom: 80px;
  left: 50%;
  transform: translateX(-50%);
  width: 80%;
  max-width: 300px;
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(0, 0, 0, 0.5);
  padding: 10px 20px;
  border-radius: 30px;
  z-index: 50;
  color: white;
}

.zoom-control input[type=range] {
  flex: 1;
  height: 4px;
}

.zoom-icon {
  font-size: 20px;
  font-weight: bold;
}

.zoom-value {
  font-size: 14px;
  width: 30px;
  text-align: right;
}
</style>