<template>
  <div class="image-uploader">
    <div 
      v-if="!imageUrl"
      @click="triggerFileInput"
      @dragover.prevent
      @dragenter.prevent
      @drop.prevent="handleDrop"
      class="upload-area border-2 border-dashed border-white/20 rounded-lg p-8 text-center cursor-pointer hover:border-art-accent transition-colors"
      :class="{ 'border-art-accent': isDragging }"
    >
      <input
        ref="fileInput"
        type="file"
        accept="image/*"
        @change="handleFileSelect"
        class="hidden"
      />
      <div class="space-y-2">
        <i data-lucide="upload" class="w-12 h-12 mx-auto text-art-muted"></i>
        <p class="text-sm text-art-muted">点击或拖拽图片到此处上传</p>
        <p class="text-xs text-art-muted/50">支持 JPG、PNG、GIF 格式</p>
      </div>
    </div>
    
    <div v-else class="image-preview relative group">
      <img :src="imageUrl" alt="Preview" class="w-full h-auto rounded-lg" />
      <div class="absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity rounded-lg flex items-center justify-center gap-2">
        <button
          @click="removeImage"
          class="px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600 transition-colors"
        >
          删除
        </button>
        <button
          @click="triggerFileInput"
          class="px-4 py-2 bg-art-accent text-white rounded hover:bg-opacity-80 transition-colors"
        >
          更换
        </button>
      </div>
    </div>
    
    <div v-if="uploading" class="mt-4 text-center">
      <div class="inline-flex items-center gap-2 text-art-accent">
        <div class="animate-spin rounded-full h-4 w-4 border-t-2 border-b-2 border-art-accent"></div>
        <span class="text-sm">上传中...</span>
      </div>
    </div>
    
    <div v-if="error" class="mt-4 text-center text-red-500 text-sm">
      {{ error }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue'
import { useToast } from '../composables/useToast'

const props = defineProps<{
  modelValue?: string
  categoryId?: number
}>()

const emit = defineEmits<{
  'update:modelValue': [value: string]
}>()

const fileInput = ref<HTMLInputElement | null>(null)
const imageUrl = ref<string>(props.modelValue || '')
const uploading = ref(false)
const error = ref('')
const isDragging = ref(false)

const toast = useToast()

watch(() => props.modelValue, (newVal) => {
  imageUrl.value = newVal || ''
})

const triggerFileInput = () => {
  fileInput.value?.click()
}

const handleFileSelect = (e: Event) => {
  const target = e.target as HTMLInputElement
  if (target.files && target.files[0]) {
    uploadFile(target.files[0])
  }
}

const handleDrop = (e: DragEvent) => {
  isDragging.value = false
  if (e.dataTransfer?.files && e.dataTransfer.files[0]) {
    uploadFile(e.dataTransfer.files[0])
  }
}

const uploadFile = async (file: File) => {
  if (!file.type.startsWith('image/')) {
    error.value = '请选择图片文件'
    return
  }

  uploading.value = true
  error.value = ''

  try {
    const formData = new FormData()
    formData.append('file', file)
    if (props.categoryId) {
      formData.append('categoryId', props.categoryId.toString())
    }
    formData.append('storageType', 'local')

    const token = localStorage.getItem('token')
    const response = await fetch('http://localhost:8081/api/admin/attachments/upload', {
      method: 'POST',
      headers: {
        ...(token ? { Authorization: `Bearer ${token}` } : {})
      },
      body: formData
    })

    if (!response.ok) {
      const errorData = await response.json()
      throw new Error(errorData.message || '上传失败')
    }

    const data = await response.json()
    imageUrl.value = data.result.fileUrl
    emit('update:modelValue', data.result.fileUrl)
    toast.showToast('图片上传成功', 'success')
  } catch (err: any) {
    error.value = err.message || '上传失败，请重试'
    toast.showToast(error.value, 'error')
  } finally {
    uploading.value = false
  }
}

const removeImage = () => {
  imageUrl.value = ''
  emit('update:modelValue', '')
  if (fileInput.value) {
    fileInput.value.value = ''
  }
}
</script>

<style scoped>
.upload-area {
  min-height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>
