﻿<script setup>
import { onMounted, ref } from "vue";
import "cropperjs";
import { useI18n } from "vue-i18n";
const { t, locale } = useI18n();
const cro_sele = ref();
const cro_canv = ref();
const cro_imag = ref();
var cor_size_width = 300;
var cor_size_height = 300;
const is_have_URL = ref(false);
const reader = new FileReader();
reader.onload = () => { initCropper(reader.result); };
const emit = defineEmits(['crop-data-url', 'crop-error'])
onMounted(() => {
  cro_sele.value.$change(0, 0, cor_size_width, cor_size_height);
  cro_canv.value.style.width = cor_size_width.toString() + "px";
  cro_canv.value.style.height = cor_size_height.toString() + "px";
  cro_imag.value.src = "";
});
function initCropper(imageSrc) { is_have_URL.value = true; cro_imag.value.src = imageSrc; }
function cancel() { is_have_URL.value = false; }
function inputfile(e) {
  const file = e.target.files[0]; if (!file) { e.target.value = ""; is_have_URL.value = false; return; }
  if (!file.type.startsWith("image/")) { e.target.value = ""; is_have_URL.value = false; return; }
  reader.readAsDataURL(file);
}
function openFilePicker() {
  const fileInput = document.createElement("input");
  fileInput.type = "file"; fileInput.accept = "image/*"; fileInput.multiple = false;
  fileInput.onchange = (e) => { inputfile(e); };
  fileInput.click();
}
function getsele() {
  console.log('getsele called, checking elements:', {
    cro_canv: cro_canv.value,
    cro_sele: cro_sele.value,
    cro_imag: cro_imag.value,
  })
  
  // 使用async函数处理异步裁剪逻辑
  const cropImage = async () => {
    try {
      console.log('Starting crop process')
      
      // 方法1: 尝试调用原生的toCanvas方法（如果可用）
      if (cro_canv.value && typeof cro_canv.value.$toCanvas === 'function') {
        console.log('Using $toCanvas method')
        try {
          const result = await cro_canv.value.$toCanvas()
          console.log('$toCanvas result type:', typeof result, 'value:', result)
          
          // 检查结果类型，如果是Canvas元素则转换为data URL
          if (result) {
            let dataUrl
            if (result instanceof HTMLCanvasElement) {
              // 如果是Canvas对象，转换为data URL
              console.log('Converting HTMLCanvasElement to data URL')
              dataUrl = result.toDataURL('image/jpeg', 0.9)
            } else if (typeof result === 'string' && result.startsWith('data:image/')) {
              // 如果已经是data URL，直接使用
              dataUrl = result
            } else {
              // 其他情况，不直接发送
              console.warn('$toCanvas returned unexpected type:', typeof result)
              throw new Error('Unexpected return type from $toCanvas')
            }
            
            if (dataUrl) {
              console.log('Generated data URL from $toCanvas, length:', dataUrl.length)
              emit('crop-data-url', dataUrl)
              return  // 成功，结束函数
            }
          }
          console.log('$toCanvas returned empty or invalid result, falling back to manual crop')
        } catch (error) {
          console.warn('$toCanvas failed, using manual crop:', error.message)
        }
      }
      
      // 方法2: 使用手动裁剪方法
      console.log('Falling back to manual crop method')
      
      // 获取图像元素
      const img = cro_imag.value
      if (!img) {
        console.error('No image element found')
        emit('crop-error', '未找到图像')
        return
      }
      
      // 等待图像加载完成
      if (!img.complete) {
        console.log('Waiting for image to load...')
        await new Promise((resolve) => {
          img.onload = resolve
          img.onerror = resolve  // 即使加载失败也继续
          // 设置超时，防止无限等待
          setTimeout(resolve, 3000)
        })
      }
      
      if (!img.complete || img.naturalWidth === 0) {
        console.error('Image failed to load or has 0 dimensions')
        emit('crop-error', '图像加载失败')
        return
      }
      
      console.log('Image loaded successfully:', img.naturalWidth, 'x', img.naturalHeight)
      
      // 获取canvas的尺寸
      const canvasRect = cro_canv.value?.getBoundingClientRect?.() || {
        width: cor_size_width,
        height: cor_size_height,
        left: 0,
        top: 0
      }
      
      console.log('Canvas rectangle:', canvasRect)
      
      // 获取选择区域
      let selectionRect = null
      if (cro_sele.value && typeof cro_sele.value.$getRect === 'function') {
        selectionRect = cro_sele.value.$getRect()
        console.log('Selection rect:', selectionRect)
      }
      
      // 验证选择区域
      if (!selectionRect || !selectionRect.width || !selectionRect.height) {
        selectionRect = {
          left: 0,
          top: 0,
          width: canvasRect.width,
          height: canvasRect.height
        }
        console.log('Using entire canvas as selection:', selectionRect)
      }
      
      // 创建输出canvas
      const outputCanvas = document.createElement('canvas')
      outputCanvas.width = selectionRect.width
      outputCanvas.height = selectionRect.height
      const ctx = outputCanvas.getContext('2d')
      
      // 设置白色背景
      ctx.fillStyle = '#ffffff'
      ctx.fillRect(0, 0, outputCanvas.width, outputCanvas.height)
      
      // 计算图像在canvas中的显示方式
      const imgAspect = img.naturalWidth / img.naturalHeight
      const canvasAspect = canvasRect.width / canvasRect.height
      
      let drawWidth, drawHeight, drawX, drawY
      
      if (imgAspect > canvasAspect) {
        // 图像更宽，高度适配
        drawHeight = canvasRect.height
        drawWidth = canvasRect.height * imgAspect
        drawX = (canvasRect.width - drawWidth) / 2
        drawY = 0
      } else {
        // 图像更高，宽度适配
        drawWidth = canvasRect.width
        drawHeight = canvasRect.width / imgAspect
        drawX = 0
        drawY = (canvasRect.height - drawHeight) / 2
      }
      
      console.log('Image display info:', { drawX, drawY, drawWidth, drawHeight })
      
      // 计算裁剪区域（将选择区域转换到图像坐标）
      const cropX = Math.max(0, (selectionRect.left - drawX) / drawWidth * img.naturalWidth)
      const cropY = Math.max(0, (selectionRect.top - drawY) / drawHeight * img.naturalHeight)
      const cropWidth = Math.min(
        (selectionRect.width / drawWidth) * img.naturalWidth,
        img.naturalWidth - cropX
      )
      const cropHeight = Math.min(
        (selectionRect.height / drawHeight) * img.naturalHeight,
        img.naturalHeight - cropY
      )
      
      console.log('Final crop coordinates (image space):', {
        cropX, cropY, cropWidth, cropHeight
      })
      
      // 执行裁剪
      ctx.drawImage(
        img,
        cropX, cropY, cropWidth, cropHeight,      // 源图像裁剪区域
        0, 0, outputCanvas.width, outputCanvas.height  // 目标canvas区域
      )
      
      // 生成data URL（JPEG格式，质量0.9）
      const dataUrl = outputCanvas.toDataURL('image/jpeg', 0.9)
      console.log('Generated crop data URL, length:', dataUrl.length)
      
      // 确保我们发送的是有效的data URL字符串
      if (typeof dataUrl === 'string' && dataUrl.startsWith('data:image/')) {
        emit('crop-data-url', dataUrl)
      } else {
        console.error('Invalid data URL generated:', typeof dataUrl)
        emit('crop-error', '生成的数据URL无效')
      }
      
    } catch (error) {
      console.error('Crop process error:', error)
      emit('crop-error', '裁剪过程中发生错误：' + error.message)
    }
  }
  
  // 执行裁剪
  cropImage()
}
</script>

<template>
  <div class="space-y-4">
    <!-- Header and Instruction -->
    <div class="flex items-center justify-between">
      <div class="space-y-1">
        <h4 class="text-sm font-semibold text-gray-900 dark:text-white">{{ t('cropper.upload_image') }}</h4>
        <p class="text-xs text-gray-500 dark:text-gray-400">{{ t('cropper.supported_formats') }}</p>
      </div>
      <button 
        v-show="!is_have_URL"
        class="group flex items-center gap-2 rounded-lg bg-gradient-to-r from-blue-600 to-blue-500 px-4 py-2.5 text-sm font-medium text-white shadow-sm transition-all hover:from-blue-700 hover:to-blue-600 hover:shadow-md focus:outline-none focus:ring-2 focus:ring-blue-500/30"
        @click="openFilePicker"
      >
        <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" />
        </svg>
        {{ t("cropper.select_image") }}
      </button>
    </div>

    <!-- Cropper Area -->
    <div v-show="is_have_URL" class="rounded-xl border border-gray-200 bg-gray-50/50 p-4 dark:border-gray-800 dark:bg-gray-900/30">
      <cropper-canvas 
        ref="cro_canv" 
        class="cropper-container mx-auto"
        :hidden="!is_have_URL" 
        background 
        scale-step="0.1"
      >
        <cropper-image ref="cro_imag" src="" alt="Picture" initialCenterSize="cover" rotatable scalable skewable translatable></cropper-image>
        <cropper-shade hidden></cropper-shade>
        <cropper-handle action="move" plain></cropper-handle>
        <cropper-selection ref="cro_sele">
          <cropper-grid role="grid" covered></cropper-grid>
          <cropper-crosshair centered></cropper-crosshair>
          <cropper-handle action="move" theme-color="rgba(255, 255, 255, 0)"></cropper-handle>
        </cropper-selection>
      </cropper-canvas>
      
      <!-- Cropper Actions -->
      <div class="mt-4 flex flex-wrap items-center justify-between gap-3">
        <div class="text-xs text-gray-500 dark:text-gray-400">
          <span class="inline-flex items-center gap-1">
            <svg class="h-3 w-3" fill="currentColor" viewBox="0 0 20 20">
              <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-11a1 1 0 10-2 0v3.586L7.707 9.293a1 1 0 00-1.414 1.414l3 3a1 1 0 001.414 0l3-3a1 1 0 00-1.414-1.414L11 10.586V7z" clip-rule="evenodd" />
            </svg>
            {{ t('cropper.drag_to_resize') }}
          </span>
        </div>
        
        <div class="flex gap-2">
          <button 
            class="group flex items-center gap-2 rounded-lg bg-gradient-to-r from-blue-600 to-blue-500 px-4 py-2 text-sm font-medium text-white shadow-sm transition-all hover:from-blue-700 hover:to-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-500/30"
            @click="getsele"
          >
            <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
            </svg>
            {{ t("cropper.crop_image") }}
          </button>
          <button 
            class="rounded-lg border border-gray-300 px-4 py-2 text-sm font-medium text-gray-700 transition-colors hover:bg-gray-50 hover:border-gray-400 dark:border-gray-700 dark:text-gray-300 dark:hover:bg-gray-800 dark:hover:border-gray-600"
            @click="cancel"
          >
            {{ t("cropper.closs") }}
          </button>
        </div>
      </div>
    </div>

    <!-- Preview Area (when image selected but not cropped) -->
    <!-- <div v-show="!is_have_URL" class="rounded-lg border-2 border-dashed border-gray-300 bg-gray-50/50 p-8 text-center dark:border-gray-700 dark:bg-gray-900/20">
      <div class="mx-auto max-w-xs">
        <svg class="mx-auto h-12 w-12 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
        </svg>
        <h4 class="mt-4 text-sm font-medium text-gray-900 dark:text-white">{{ t('cropper.ready_to_upload') }}</h4>
        <p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
          {{ t('cropper.click_button_or_drag') }}
        </p>
      </div>
    </div> -->
  </div>
</template>

<style scoped>
.cropper-container {
  width: 100%;
  max-width: 400px;
  height: 300px;
  border-radius: 12px;
  box-shadow: 0 8px 25px -5px rgba(0, 0, 0, 0.08), 0 4px 10px -2px rgba(0, 0, 0, 0.04);
  overflow: hidden;
  border: 1px solid rgba(0, 0, 0, 0.05);
  transition: box-shadow 0.2s ease;
}

.cropper-container:hover {
  box-shadow: 0 12px 32px -8px rgba(0, 0, 0, 0.12), 0 6px 14px -4px rgba(0, 0, 0, 0.06);
}

.dark .cropper-container {
  box-shadow: 0 8px 25px -5px rgba(0, 0, 0, 0.25), 0 4px 10px -2px rgba(0, 0, 0, 0.15);
  border: 1px solid rgba(255, 255, 255, 0.05);
}

.dark .cropper-container:hover {
  box-shadow: 0 12px 32px -8px rgba(0, 0, 0, 0.35), 0 6px 14px -4px rgba(0, 0, 0, 0.2);
}
</style>
