<template>
  <div class="video-image-uploader">
    <div class="image-list">
      <div
        v-for="(item, index) in localPreviewList"
        :key="item.uid"
        class="image-item"
      >
        <img :src="item.url" class="uploaded-image" :alt="getFrameLabel(index)" />
        <div class="frame-label">{{ getFrameLabel(index) }}</div>
        <div class="delete-icon" @click.stop="handleDelete(index)">
          <i-ep-close />
        </div>
      </div>
      <template v-for="i in maxImages" :key="i">
        <div
          v-if="localPreviewList.length < maxImages && !localPreviewList[i - 1]"
          class="upload-trigger"
          @click="triggerUpload(i - 1)"
        >
          <i-ep-plus color="#333333" />
          <div class="upload-text">{{ getUploadText(i) }}</div>
        </div>
      </template>
    </div>
    <el-upload
      v-for="i in maxImages"
      v-show="false"
      :key="i"
      :ref="el => setUploadRef(el, i - 1)"
      :action="uploadurl"
      :limit="1"
      :before-upload="beforeUpload"
      :on-success="(response, uploadFile) => handleSuccess(response, uploadFile, i - 1)"
      :on-error="handleError"
    />
  </div>
</template>

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

const props = defineProps({
  modelType: {
    type: String,
    default: 'text'
  },
  imagesCount: {
    type: Number,
    default: 1
  },
  modelValue: {
    type: Array,
    default: () => []
  }
})

const emit = defineEmits(['update:modelValue'])

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

const showEndFrame = computed(() => props.modelType === 'image' && props.imagesCount === 2)
const maxImages = computed(() => props.modelType === 'image' ? (showEndFrame.value ? 2 : 1) : 1)

const setUploadRef = (el, index) => {
  if (el) {
    uploadRefs.value[index] = el
  }
}

const getFrameLabel = (index) => {
  if (props.modelType === 'digitalHuman') {
    return ''
  }
  return index === 0 ? '首帧' : '尾帧'
}

const getUploadText = (i) => {
  if (props.modelType === 'digitalHuman') {
    return '参考内容'
  }
  return i === 1 ? '首帧' : '尾帧'
}

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 = (index) => {
  if (uploadRefs.value[index]) {
    uploadRefs.value[index].$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, index) => {
  ElMessage.success('上传成功')

  isUploading.value = true

  const localUrl = URL.createObjectURL(uploadFile.raw)

  const newImage = {
    uid: uploadFile.uid,
    url: response.url
  }

  if (imageList.value[index]) {
    const previewItem = localPreviewList.value[index]
    if (previewItem && previewItem.url && previewItem.url.startsWith('blob:')) {
      URL.revokeObjectURL(previewItem.url)
    }
    imageList.value[index] = newImage
    localPreviewList.value[index] = {
      uid: uploadFile.uid,
      url: localUrl,
      serverUrl: response.url
    }
  } else {
    imageList.value[index] = newImage
    localPreviewList.value[index] = {
      uid: uploadFile.uid,
      url: localUrl,
      serverUrl: response.url
    }
  }

  emit('update:modelValue', [...imageList.value])

  nextTick(() => {
    isUploading.value = false
  })
}

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

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 handleSelect = async (url, index = 0) => {
  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 (uploadRefs.value[index]) {
    uploadRefs.value[index].handleStart(file)
    uploadRefs.value[index].submit()
  }
}

defineExpose({
  handleSelect
})
</script>

<style lang="less" scoped>
.video-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;
  }

  .frame-label {
    position: absolute;
    bottom: 4px;
    right: 4px;
    width: 32px;
    height: 20px;
    background: rgba(0, 15, 51, 0.8);
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-size: 10px;
    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;
  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;
    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>
