<template>
  <view class="page">

    <!-- ① 视频预览层（拿到 MediaStream 后才显示） -->
    <video
      ref="video"
      class="video"
      playsinline webkit-playsinline x5-playsinline
      muted    
      v-if="started"
    />

    <!-- ② Canvas：实时把 video 画上来，同时用于拍照 -->
    <canvas ref="canvas" class="canvas" v-if="started"></canvas>

    <!-- ③ 中间遮罩 -->
    <image
      class="overlay"
      src="https://www.focusnu.com/media/directive/index/nu.png"
      :style="{ opacity: started ? 1 : 0 }"
    />

    <!-- ④ 按钮区 -->
    <view class="btn-bar" v-if="started">
      <button class="btn close" @click="close">关闭</button>
      <button class="btn shoot" @click="shoot"></button>
    </view>

    <!-- ⑤ 首次进入的 【开始拍照】 按钮（触发权限弹窗） -->
    <view class="starter" v-if="!started">
      <button class="btn start" @click="startCamera">开始拍照</button>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, onBeforeUnmount } from 'vue'
import { useRouter } from 'vue-router'

// ----------------- 视图引用 -----------------
const video  = ref<HTMLVideoElement>()
const canvas = ref<HTMLCanvasElement>()

// ----------------- 状态 -----------------
const started = ref(false)
let stream: MediaStream | null = null
let rafID: number

// ----------------- 逻辑 -----------------
async function startCamera() {
  // 1. 环境检测
  if (!navigator.mediaDevices?.getUserMedia) {
    uni.showToast({ title: '当前浏览器不支持实时相机', icon: 'none' })
    return
  }

  try {
    stream = await navigator.mediaDevices.getUserMedia({
      video: { facingMode: { ideal: 'environment' } },
      audio: false
    })

    // 2. 让 <video> 播起来
    const v = video.value!
    v.srcObject = stream
    await v.play()

    // 3. 启动渲染循环，把视频帧 real-time 画到 Canvas
    drawFrame()
    started.value = true
  } catch (err) {
    console.error(err)
    uni.showToast({ title: '无法获取摄像头权限', icon: 'none' })
  }
}

function drawFrame() {
  if (!started.value) return
  const v = video.value!, c = canvas.value!
  const ctx = c.getContext('2d')!

  if (v.videoWidth && v.videoHeight) {
    // 每帧同步 canvas 尺寸，否则会变形
    if (c.width !== window.innerWidth) {
      c.width  = window.innerWidth
      c.height = window.innerHeight
    }
    ctx.drawImage(v, 0, 0, c.width, c.height)
  }
  rafID = requestAnimationFrame(drawFrame)
}

function shoot() {
  const dataURL = canvas.value!.toDataURL('image/jpeg', 0.9)
  // 这里你可以：直接预览 / 上传 oss / emit 给父页
  uni.navigateBack()
  uni.$emit('photoTaken', dataURL)
}

function close() {
  cleanup()
  uni.navigateBack()
}

function cleanup() {
  cancelAnimationFrame(rafID)
  if (stream) stream.getTracks().forEach(t => t.stop())
}

onBeforeUnmount(cleanup)
</script>

<style scoped>
.page   { position:fixed; inset:0; background:#000; overflow:hidden; }
.video  { position:absolute; inset:0; object-fit:cover; z-index:1; }
.canvas { position:absolute; inset:0; z-index:1; }
.overlay{
  position:absolute; top:50%; left:50%;
  width:220px; height:220px;
  transform:translate(-50%,-50%); z-index:2;
  pointer-events:none;
}
.btn-bar{
  position:absolute; bottom:60px; inset-inline:0;
  display:flex; justify-content:space-around; z-index:3;
}
.btn{
  border:none; font-size:16px; color:#fff;
}
.close{ width:100px; height:40px; border-radius:20px; background:rgba(0,0,0,.5); }
.shoot{ width:80px; height:80px; border-radius:40px; background:#fff; }
.starter{
  position:absolute; inset:0; display:flex;
  justify-content:center; align-items:center; z-index:3;
  background:#000;
}
.start{ width:140px; height:46px; border-radius:23px; background:#1aad19; }
</style>
