<template>
  <div class="camera-container is-fullscreen">
    <div v-if="error" class="error-message">
      {{ error }}
      <el-button style="margin-top: 20px" @click="handleCancel">关闭</el-button>
    </div>

    <div v-else class="media-box">
      <video
          v-show="!imgSrc"
          ref="videoRef"
          autoplay
          playsinline
          class="media-content video-feed"
          :style="{ transform: `scale(${cameraZoom})` }"
      ></video>

      <div v-show="imgSrc" class="editor-container">
        <img
            ref="previewImgRef"
            :src="imgSrc"
            class="media-content preview-img"
            alt="Photo Preview"
        />
      </div>

      <canvas ref="canvasRef" style="display: none;"></canvas>
    </div>

    <div v-if="!imgSrc && isCameraReady" class="zoom-slider-container">
      <el-icon class="zoom-icon"><Remove /></el-icon>
      <el-slider
          v-model="cameraZoom"
          :min="1"
          :max="3"
          :step="0.1"
          :show-tooltip="false"
          class="custom-slider"
      />
      <el-icon class="zoom-icon"><CirclePlus /></el-icon>
    </div>

    <div class="camera-actions">

      <template v-if="!imgSrc">
        <el-button circle size="large" @click="handleCancel" class="action-btn icon-btn">
          <el-icon><Close /></el-icon>
        </el-button>

        <el-button
            circle
            type="danger"
            size="large"
            @click="capture"
            :disabled="!isCameraReady"
            class="shutter-btn"
        >
          <div class="shutter-inner"></div>
        </el-button>

        <div class="placeholder-btn"></div>
      </template>

      <template v-else>

        <div v-if="isEditing" class="edit-mode-bar">
          <div class="edit-tools">
            <el-tooltip content="切换移动图片/调整裁剪框" placement="top" :show-after="1000">
              <el-button
                  circle
                  @click="toggleDragMode"
                  class="tool-btn"
                  :class="{ 'is-active': isMoveMode }"
              >
                <el-icon><Rank /></el-icon>
              </el-button>
            </el-tooltip>

            <el-divider direction="vertical" border-style="dashed" />

            <el-button circle @click="zoomCropper(0.1)" class="tool-btn"><el-icon><ZoomIn /></el-icon></el-button>
            <el-button circle @click="zoomCropper(-0.1)" class="tool-btn"><el-icon><ZoomOut /></el-icon></el-button>

            <el-button circle @click="rotateLeft" class="tool-btn"><el-icon><RefreshLeft /></el-icon></el-button>
            <el-button circle @click="rotateRight" class="tool-btn"><el-icon><RefreshRight /></el-icon></el-button>
            <el-button circle @click="resetCrop" class="tool-btn"><el-icon><Refresh /></el-icon></el-button>
          </div>

          <div class="edit-confirm">
            <el-button circle size="large" @click="handleCancel" class="action-btn icon-btn">
              <el-icon><Close /></el-icon>
            </el-button>

            <el-button @click="stopEdit" class="text-btn">取消编辑</el-button>
            <el-button type="success" @click="confirmUse" class="confirm-btn">
              完成并上传
            </el-button>
          </div>
        </div>

        <div v-else class="preview-mode-bar">
          <el-button circle size="large" @click="handleCancel" class="action-btn icon-btn">
            <el-icon><Close /></el-icon>
          </el-button>

          <el-button @click="retake" size="large" class="text-btn" style="min-width: 80px;">重拍</el-button>

          <el-button @click="startEdit" size="large" class="text-btn" style="min-width: 80px;">
            <el-icon style="margin-right: 4px"><Edit /></el-icon>编辑
          </el-button>

          <el-button
              type="success"
              @click="confirmUse"
              size="large"
              class="confirm-btn"
          >
            确认使用 <el-icon class="el-icon--right"><Check /></el-icon>
          </el-button>
        </div>

      </template>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import {
  Camera, RefreshLeft, RefreshRight, Check, Close, Refresh, Edit,
  ZoomIn, ZoomOut, Remove, CirclePlus, Rank
} from '@element-plus/icons-vue'
import Cropper from 'cropperjs'
import 'cropperjs/dist/cropper.css'

const emit = defineEmits(['photo-submit', 'cancel'])

const videoRef = ref<HTMLVideoElement>()
const canvasRef = ref<HTMLCanvasElement>()
const previewImgRef = ref<HTMLImageElement>()
const mediaStream = ref<MediaStream>()
const error = ref('')
const isCameraReady = ref(false)

const imgSrc = ref('')
const currentFile = ref<File | null>(null)

const isEditing = ref(false)
const isMoveMode = ref(false)
const cameraZoom = ref(1) // 控制拍摄时的变焦倍数
let cropper: Cropper | null = null

const startCamera = async () => {
  stopCamera()
  error.value = ''
  imgSrc.value = ''
  isEditing.value = false
  currentFile.value = null
  cameraZoom.value = 1

  try {
    const constraints = {
      video: {
        facingMode: 'environment',
        width: { ideal: 1920 },
        height: { ideal: 1080 }
      }
    }
    const stream = await navigator.mediaDevices.getUserMedia(constraints)
    mediaStream.value = stream

    if (videoRef.value) {
      videoRef.value.srcObject = stream
      await videoRef.value.play()
      isCameraReady.value = true
    }
  } catch (err: any) {
    console.error(err)
    if (location.protocol !== 'https:' && location.hostname !== 'localhost') {
      error.value = '无法访问摄像头: 请使用 HTTPS 环境。'
    } else {
      error.value = '无法访问摄像头: ' + (err.message || '请检查权限')
    }
    ElMessage.error(error.value)
  }
}

const stopCamera = () => {
  if (mediaStream.value) {
    mediaStream.value.getTracks().forEach(track => track.stop())
    mediaStream.value = undefined
  }
  if (videoRef.value) {
    videoRef.value.srcObject = null
  }
  isCameraReady.value = false
}

// ----------------------------------------------------
// 核心修复：拍照时应用数码变焦（裁剪+拉伸）
// ----------------------------------------------------
const capture = () => {
  const video = videoRef.value
  const canvas = canvasRef.value
  if (!video || !canvas) return

  // 1. 获取视频原始尺寸
  const vW = video.videoWidth
  const vH = video.videoHeight
  if (vW === 0 || vH === 0) return

  // 2. 设置画布为全尺寸（保持清晰度）
  canvas.width = vW
  canvas.height = vH

  const ctx = canvas.getContext('2d')
  if (!ctx) return

  // 3. 计算基于 zoomLevel 的裁剪区域
  // zoom = 1: 裁剪宽 = vW
  // zoom = 2: 裁剪宽 = vW / 2
  const zoom = cameraZoom.value
  const cropW = vW / zoom
  const cropH = vH / zoom

  // 4. 计算裁剪的起始点 (居中裁剪)
  const cropX = (vW - cropW) / 2
  const cropY = (vH - cropH) / 2

  // 5. 将裁剪区域绘制到全尺寸画布上 (drawImage(source, sx, sy, sw, sh, dx, dy, dw, dh))
  ctx.drawImage(
      video,
      cropX, cropY, cropW, cropH, // 源：截取中心部分
      0, 0, vW, vH                // 目标：铺满整个画布
  )

  canvas.toBlob((blob) => {
    if (!blob) {
      ElMessage.error('拍照失败，请重试')
      return
    }

    const timestamp = new Date().getTime()
    const filename = `photo_${timestamp}.jpg`
    currentFile.value = new File([blob], filename, { type: 'image/jpeg' })

    imgSrc.value = URL.createObjectURL(blob)
    stopCamera()
  }, 'image/jpeg', 0.95)
}

const retake = () => {
  destroyCropper()
  isEditing.value = false
  if (imgSrc.value) URL.revokeObjectURL(imgSrc.value)
  imgSrc.value = ''
  currentFile.value = null
  startCamera()
}

const startEdit = () => {
  if (!imgSrc.value || !previewImgRef.value) return
  isEditing.value = true
  isMoveMode.value = false

  nextTick(() => {
    if (cropper) cropper.destroy()

    cropper = new Cropper(previewImgRef.value!, {
      viewMode: 1,
      dragMode: 'none',
      autoCropArea: 0.8,
      background: false,
      modal: true,
      guides: true,
      highlight: false,
      cropBoxMovable: true,
      cropBoxResizable: true,
      toggleDragModeOnDblclick: false,
      movable: true,
      zoomable: true,
      rotatable: true,
      scalable: true,
    })
  })
}

const toggleDragMode = () => {
  if (!cropper) return
  isMoveMode.value = !isMoveMode.value
  cropper.setDragMode(isMoveMode.value ? 'move' : 'none')
}

const stopEdit = () => {
  destroyCropper()
  isEditing.value = false
}

const destroyCropper = () => {
  if (cropper) {
    cropper.destroy()
    cropper = null
  }
}

const rotateLeft = () => cropper?.rotate(-90)
const rotateRight = () => cropper?.rotate(90)
const resetCrop = () => {
  cropper?.reset()
  isMoveMode.value = false
  cropper?.setDragMode('none')
}
const zoomCropper = (ratio: number) => cropper?.zoom(ratio)

const confirmUse = () => {
  console.log('👆 确认使用')

  if (isEditing.value && cropper) {
    const croppedCanvas = cropper.getCroppedCanvas({
      imageSmoothingQuality: 'high'
    })

    if (!croppedCanvas) {
      ElMessage.error('图片处理失败')
      return
    }

    croppedCanvas.toBlob((blob) => {
      if (!blob) {
        ElMessage.error('文件生成失败')
        return
      }
      const timestamp = new Date().getTime()
      const filename = `photo_crop_${timestamp}.jpg`
      const file = new File([blob], filename, { type: 'image/jpeg' })

      emitFile(file)
    }, 'image/jpeg', 0.9)
  }
  else if (currentFile.value) {
    emitFile(currentFile.value)
  }
  else {
    ElMessage.warning('没有可用的照片')
  }
}

const emitFile = (file: File) => {
  try {
    console.log('📤 提交文件:', file.name, (file.size/1024).toFixed(1)+'KB')
    emit('photo-submit', file)
  } catch (err) {
    console.error('父组件处理事件失败:', err)
  }
}

const handleCancel = () => {
  destroyCropper()
  stopCamera()
  emit('cancel')
}

onMounted(() => startCamera())
onBeforeUnmount(() => {
  destroyCropper()
  stopCamera()
  if (imgSrc.value) URL.revokeObjectURL(imgSrc.value)
})

defineExpose({ startCamera, stopCamera })
</script>

<style scoped>
.camera-container.is-fullscreen {
  position: fixed;
  top: 0; left: 0; width: 100vw; height: 100vh;
  background-color: #000;
  z-index: 9999;
  display: flex; flex-direction: column;
}

.error-message {
  color: #fff;
  padding: 40px;
  text-align: center;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

/* 媒体显示区 */
.media-box {
  flex: 1;
  width: 100%;
  position: relative;
  overflow: hidden;
  background: #000;
  display: flex;
  justify-content: center;
  align-items: center;
}

.media-content {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.2s ease-out; /* 变焦平滑动画 */
  transform-origin: center center;
}

.editor-container { width: 100%; height: 100%; }
.preview-img { display: block; max-width: 100%; max-height: 100%; }

/* 变焦滑块 */
.zoom-slider-container {
  position: absolute;
  bottom: 150px;
  left: 50%;
  transform: translateX(-50%);
  width: 70%;
  max-width: 300px;
  display: flex;
  align-items: center;
  gap: 10px;
  z-index: 20;
  background: rgba(0, 0, 0, 0.4);
  padding: 5px 15px;
  border-radius: 20px;
}

.zoom-icon { color: #fff; font-size: 18px; }
.custom-slider { flex: 1; }
:deep(.el-slider__runway) { background-color: #555; }
:deep(.el-slider__bar) { background-color: #fff; }
:deep(.el-slider__button) { border-color: #fff; }

/* 底部操作栏 */
.camera-actions {
  height: 140px;
  width: 100%;
  background: rgba(0, 0, 0, 0.85);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding-bottom: 10px;
  position: relative;
  z-index: 30;
}

/* 拍照按钮布局 */
.camera-actions:has(.shutter-btn) {
  flex-direction: row;
  justify-content: space-around;
  align-items: center;
}

.placeholder-btn { width: 40px; }

/* 按钮样式 */
.action-btn { background: rgba(255, 255, 255, 0.15); border: none; color: #fff; }

.text-btn {
  color: #fff;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.3);
  font-size: 14px;
}
.confirm-btn { min-width: 120px; font-weight: bold; }

/* 快门按钮 */
.shutter-btn {
  width: 72px;
  height: 72px;
  border: 4px solid #fff;
  background: transparent !important;
  padding: 0;
  display: flex;
  justify-content: center;
  align-items: center;
}
.shutter-inner {
  width: 58px;
  height: 58px;
  background-color: #fff;
  border-radius: 50%;
  transition: transform 0.1s;
}
.shutter-btn:active .shutter-inner {
  transform: scale(0.9);
  background-color: #ccc;
}

/* 预览模式操作栏 */
.preview-mode-bar {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 20px;
  gap: 10px;
}

/* 编辑模式操作栏 */
.edit-mode-bar {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 15px;
}
.edit-tools {
  display: flex;
  justify-content: center;
  gap: 12px;
  align-items: center;
}
.tool-btn {
  background: rgba(255, 255, 255, 0.1);
  border: none;
  color: #fff;
  font-size: 16px;
  transition: all 0.3s;
}
.tool-btn.is-active {
  background-color: #409EFF;
  color: #fff;
}

.edit-confirm {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 20px;
  gap: 10px;
}

/* Cropper 样式定制 */
:deep(.cropper-view-box) {
  outline: 3px solid #409EFF;
  outline-color: #409EFF;
}
:deep(.cropper-point) {
  width: 8px;
  height: 8px;
  background-color: #409EFF;
  opacity: 0.9;
}
:deep(.cropper-line) {
  background-color: rgba(64, 158, 255, 0.5);
}
</style>