<template>
  <div class="image-upload">
    <el-upload
      ref="uploadRef"
      class="upload-demo"
      :action="uploadUrl"
      :headers="uploadHeaders"
      :data="uploadData"
      :before-upload="beforeUpload"
      :on-success="handleSuccess"
      :on-error="handleError"
      :on-progress="handleProgress"
      :show-file-list="false"
      :auto-upload="true"
      accept="image/*"
    >
      <div class="upload-area" v-if="!imageUrl">
        <el-icon class="upload-icon"><Plus /></el-icon>
        <div class="upload-text">{{ placeholder || '点击上传图片' }}</div>
      </div>
      <div class="image-preview" v-else>
        <img :src="imageUrl" alt="预览图" />
        <div class="image-overlay">
          <el-icon class="preview-icon" @click.stop="previewImage"><ZoomIn /></el-icon>
          <el-icon class="delete-icon" @click.stop="deleteImage"><Delete /></el-icon>
        </div>
      </div>
    </el-upload>
    
    <!-- 上传进度 -->
    <el-progress 
      v-if="uploading" 
      :percentage="uploadProgress" 
      :stroke-width="4"
      class="upload-progress"
    />
    
    <!-- 图片预览对话框 -->
    <el-dialog v-model="previewVisible" title="图片预览" width="50%">
      <img :src="imageUrl" alt="预览图" style="width: 100%; height: auto;" />
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { Plus, ZoomIn, Delete } from '@element-plus/icons-vue'
import { useUserStore } from '@/stores/user'

const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  },
  placeholder: {
    type: String,
    default: '点击上传图片'
  },
  uploadType: {
    type: String,
    default: 'document' // document, avatar, product
  },
  maxSize: {
    type: Number,
    default: 5 // MB
  }
})

const emit = defineEmits(['update:modelValue', 'upload-success', 'upload-error'])

const userStore = useUserStore()
const uploadRef = ref()
const imageUrl = ref(props.modelValue)
const uploading = ref(false)
const uploadProgress = ref(0)
const previewVisible = ref(false)

// 上传配置
const uploadUrl = computed(() => {
  return `${import.meta.env.VITE_API_BASE_URL || 'http://localhost:3000'}/api/upload/image`
})

const uploadHeaders = computed(() => {
  const token = userStore.token
  return token ? { Authorization: `Bearer ${token}` } : {}
})

const uploadData = computed(() => {
  return { type: props.uploadType }
})

// 监听modelValue变化
watch(() => props.modelValue, (newVal) => {
  imageUrl.value = newVal
})

// 上传前验证
const beforeUpload = (file) => {
  // 检查文件类型
  const isImage = file.type.startsWith('image/')
  if (!isImage) {
    ElMessage.error('只能上传图片文件！')
    return false
  }
  
  // 检查文件大小
  const isLtMaxSize = file.size / 1024 / 1024 < props.maxSize
  if (!isLtMaxSize) {
    ElMessage.error(`图片大小不能超过 ${props.maxSize}MB！`)
    return false
  }
  
  uploading.value = true
  uploadProgress.value = 0
  return true
}

// 上传进度
const handleProgress = (event) => {
  uploadProgress.value = Math.round(event.percent)
}

// 上传成功
const handleSuccess = (response) => {
  uploading.value = false
  uploadProgress.value = 0
  
  if (response.success) {
    imageUrl.value = response.url
    emit('update:modelValue', response.url)
    emit('upload-success', response)
    ElMessage.success('图片上传成功')
  } else {
    ElMessage.error(response.message || '上传失败')
    emit('upload-error', response)
  }
}

// 上传失败
const handleError = (error) => {
  uploading.value = false
  uploadProgress.value = 0
  ElMessage.error('图片上传失败，请重试')
  emit('upload-error', error)
}

// 预览图片
const previewImage = () => {
  previewVisible.value = true
}

// 删除图片
const deleteImage = () => {
  imageUrl.value = ''
  emit('update:modelValue', '')
  ElMessage.success('图片已删除')
}
</script>

<style scoped>
.image-upload {
  width: 100%;
}

.upload-demo {
  width: 100%;
}

.upload-area {
  width: 200px;
  height: 120px;
  border: 2px dashed #d9d9d9;
  border-radius: 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: border-color 0.3s;
}

.upload-area:hover {
  border-color: #409eff;
}

.upload-icon {
  font-size: 28px;
  color: #8c939d;
  margin-bottom: 8px;
}

.upload-text {
  color: #606266;
  font-size: 14px;
}

.image-preview {
  position: relative;
  width: 200px;
  height: 120px;
  border-radius: 6px;
  overflow: hidden;
  cursor: pointer;
}

.image-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.image-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.3s;
}

.image-preview:hover .image-overlay {
  opacity: 1;
}

.preview-icon,
.delete-icon {
  color: white;
  font-size: 20px;
  margin: 0 10px;
  cursor: pointer;
  transition: transform 0.3s;
}

.preview-icon:hover,
.delete-icon:hover {
  transform: scale(1.2);
}

.upload-progress {
  margin-top: 10px;
}
</style>