<template>
  <div class="image-uploader">
    <div class="image-list">
      <div
        v-for="(item, index) in localPreviewList"
        :key="item.uid"
        class="image-item"
        @click.stop="handleImageClick(index)"
      >
        <img :src="item.url" class="uploaded-image" alt="上传的图片" />
        <div class="image-index">{{ index + 1 }}</div>
        <div class="delete-icon" @click.stop="handleDelete(index)">
          <i-ep-close />
        </div>
      </div>
      <div v-if="localPreviewList.length < limit" class="upload-trigger" @click="triggerUpload">
        <i-ep-plus color="#333333" />
        <div class="upload-text">参考内容</div>
      </div>
    </div>
    <el-upload
      ref="uploadRef"
      v-show="false"
      :action="uploadurl"
      multiple
      :limit="limit"
      :before-upload="beforeUpload"
      :on-success="handleSuccess"
      :on-error="handleError"
      :on-exceed="handleExceed"
    />
  </div>
</template>

<script setup>
import { genFileId } from 'element-plus'

const props = defineProps({
  limit: {
    type: Number,
    default: 1
  },
  /**
   * 图片列表，每个元素包含 url 和 uid 属性
   */
  modelValue: {
    type: Array,
    default: () => []
  }
})

const emit = defineEmits(['update:modelValue', 'open-canvas'])

const uploadurl = import.meta.env.VITE_API_WORKFLOW_UPLOAD
const uploadRef = ref(null)
const imageList = ref([...props.modelValue])
const localPreviewList = ref([...props.modelValue])
const isUploading = ref(false)

watch(() => props.modelValue, async (newVal) => {
  if (isUploading.value) {
    return
  }
  
  imageList.value = [...newVal]
  
  const newPreviewList = []
  for (const img of newVal) {
    let previewImg = { ...img }
    if (img.url && !img.url.startsWith('blob:')) {
      try {
        const response = await fetch(img.url)
        const blob = await response.blob()
        previewImg = {
          ...img,
          url: URL.createObjectURL(blob),
          serverUrl: img.url
        }
      } catch (error) {
        console.error('Failed to create blob URL:', error)
        previewImg = {
          ...img,
          serverUrl: img.url
        }
      }
    }
    newPreviewList.push(previewImg)
  }
  localPreviewList.value = newPreviewList
}, { deep: true, immediate: true })

const triggerUpload = () => {
  uploadRef.value.$el.querySelector('input').click()
}

const beforeUpload = (rawFile) => {
  const allowedTypes = ['image/jpeg', 'image/png']

  if (!allowedTypes.includes(rawFile.type)) {
    ElMessage.error('不支持的文件类型，请上传 JPG、PNG 格式的图片')
    return false
  }

  if (rawFile.size / 1024 / 1024 > 10) {
    ElMessage.error('图片大小不能超过 10MB')
    return false
  }
}

const handleSuccess = (response, uploadFile) => {
  ElMessage.success('上传成功')
  
  isUploading.value = true
  
  const localUrl = URL.createObjectURL(uploadFile.raw)
  
  const newImage = {
    uid: uploadFile.uid,
    url: response.url
  }
  imageList.value.push(newImage)
  emit('update:modelValue', [...imageList.value])
  
  const newPreview = {
    uid: uploadFile.uid,
    url: localUrl,
    serverUrl: response.url
  }
  localPreviewList.value.push(newPreview)
  
  nextTick(() => {
    isUploading.value = false
  })
}

const handleError = () => {
  ElMessage.error('上传失败，请重新选择图片')
}

const handleExceed = () => {
  ElMessage.warning(`最多只能上传 ${props.limit} 张图片`)
}

const handleDelete = (index) => {
  const previewItem = localPreviewList.value[index]
  if (previewItem && previewItem.url && previewItem.url.startsWith('blob:')) {
    URL.revokeObjectURL(previewItem.url)
  }
  
  localPreviewList.value.splice(index, 1)
  imageList.value.splice(index, 1)
  emit('update:modelValue', [...imageList.value])
}

const handleImageClick = (clickedIndex) => {
  const clickedImage = localPreviewList.value[clickedIndex]
  if (!clickedImage) return
  
  const otherImages = localPreviewList.value
    .filter((_, index) => index !== clickedIndex)
    .map((img, index) => ({
      ...img,
      displayIndex: index + 2
    }))
  
  emit('open-canvas', {
    mainImage: clickedImage,
    referenceImages: otherImages
  })
}

const handleSelect = async (url) => {
  const initialFile = await fetch(url)
  const blob = await initialFile.blob()
  const file = new File([blob], `selected_image_${Date.now()}.jpg`, { type: blob.type })
  file.uid = genFileId()

  if (props.limit === 1 && imageList.value.length === 1) {
    imageList.value = []
  }

  uploadRef.value.handleStart(file)
  uploadRef.value.submit()
}

defineExpose({
  handleSelect,
  triggerUpload
})
</script>

<style lang="less" scoped>
.image-uploader {
  display: flex;
  align-items: center;
}

.image-list {
  display: flex;
  gap: 8px;
  align-items: center;
}

.image-item {
  position: relative;
  width: 56px;
  height: 56px;
  cursor: pointer;
  transition: all 0.3s ease;

  &:hover {
    transform: scale(1.1);
    z-index: 10;

    .delete-icon {
      opacity: 1;
    }
  }

  .uploaded-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: all 0.3s ease;
    border-radius: 8px;
  }

  .image-index {
    position: absolute;
    bottom: 4px;
    right: 4px;
    width: 20px;
    height: 20px;
    background: rgba(0, 15, 51, 0.8);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-size: 12px;
    font-weight: bold;
    z-index: 5;
    transition: all 0.3s ease;
  }

  .delete-icon {
    position: absolute;
    top: -6px;
    right: -6px;
    width: 20px;
    height: 20px;
    background: #ef4444;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-size: 12px;
    cursor: pointer;
    opacity: 0;
    transition: all 0.3s ease;
    z-index: 20;

    &:hover {
      background: #dc2626;
      transform: scale(1.1);
    }
  }
}

.upload-trigger {
  width: 56px;
  height: 56px;
  // border: 2px dashed #d1d5db;
  background: rgba(0, 15, 51, 0.04);
  backdrop-filter: blur(5px);
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  cursor: pointer;
  color: #9ca3af;
  font-size: 15px;
  transition: all 0.3s ease;

  span {
    color: #333;
    font-family: "Microsoft YaHei";
    font-size: 12px;
    font-style: normal;
    font-weight: 400;
    line-height: normal;
  }

  &:hover {
    background-color: #F0F1F2;
    border-color: #626aef;
    // color: #626aef;
    transform: scale(1.05);
  }
}

.upload-text {
  color: #666;
  font-family: "Microsoft YaHei";
  font-size: 12px;
  font-style: normal;
  font-weight: 400;
  line-height: normal;
}
</style>
