<template>
  <div class="image-picker">
    <label v-if="label" class="block text-sm text-art-muted mb-2">{{ label }}</label>

    <div class="flex items-start gap-4">
      <!-- 预览区 -->
      <div
        class="relative shrink-0 overflow-hidden bg-white/5 border border-white/10 flex items-center justify-center"
        :class="[
          variant === 'avatar' ? 'rounded-full' : 'rounded-lg',
          previewSizeClass
        ]"
      >
        <img
          v-if="imageUrl"
          :src="imageUrl"
          alt="Preview"
          class="w-full h-full object-cover"
        />
        <span v-else class="text-art-muted/50 text-xs text-center px-2">
          {{ placeholder }}
        </span>
      </div>

      <!-- 操作区 -->
      <div class="flex-1 min-w-0 space-y-2">
        <div
          @click="triggerFileInput"
          @dragover.prevent="handleDragOver"
          @dragenter.prevent="handleDragEnter"
          @dragleave.prevent="handleDragLeave"
          @drop.prevent="handleDrop"
          class="upload-area border-2 border-dashed rounded-lg p-4 text-center cursor-pointer transition-colors"
          :class="[
            isDragging ? 'border-art-accent bg-art-accent/5' : 'border-white/20 hover:border-art-accent/50',
            disabled || uploading ? 'opacity-50 cursor-not-allowed' : ''
          ]"
        >
          <input
            ref="fileInput"
            type="file"
            :accept="accept"
            class="hidden"
            :disabled="disabled"
            @change="handleFileSelect"
          />
          <p class="text-xs text-art-muted">点击或拖拽图片到此处上传</p>
        </div>

        <div class="flex flex-wrap gap-2">
          <button
            type="button"
            class="admin-btn-secondary text-xs"
            :disabled="disabled"
            @click="openLibraryModal"
          >
            从素材库选择
          </button>
          <button
            v-if="imageUrl"
            type="button"
            class="text-xs text-red-400 hover:text-red-300 transition-colors"
            :disabled="disabled"
            @click="clearImage"
          >
            清除
          </button>
        </div>
        <p v-if="hint" class="text-xs text-art-muted/60">{{ hint }}</p>
        <p v-if="error" class="text-xs text-red-400">{{ error }}</p>
        <p v-if="uploading" class="text-xs text-art-accent">上传中...</p>
      </div>
    </div>

    <AttachmentLibraryModal
      :show="showLibraryModal"
      :multiple="false"
      :selected-urls="imageUrl ? [imageUrl] : []"
      @update:show="showLibraryModal = $event"
      @confirm="handleLibrarySelect"
    />
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { useToast } from '../../composables/useToast'
import { useImageDropUpload } from '../../composables/useImageDropUpload'
import { API_BASE, authFetch, parseApiResponse } from '../../services/api'
import AttachmentLibraryModal from './AttachmentLibraryModal.vue'

const props = withDefaults(defineProps<{
  modelValue?: string
  label?: string
  placeholder?: string
  hint?: string
  accept?: string
  disabled?: boolean
  variant?: 'avatar' | 'default'
  size?: 'sm' | 'md' | 'lg'
  categoryId?: number
}>(), {
  modelValue: '',
  placeholder: '暂无图片',
  accept: 'image/*',
  disabled: false,
  variant: 'default',
  size: 'md'
})

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

const fileInput = ref<HTMLInputElement | null>(null)
const uploading = ref(false)
const error = ref('')
const showLibraryModal = ref(false)
const toast = useToast()

const imageUrl = computed({
  get: () => props.modelValue || '',
  set: (val: string) => emit('update:modelValue', val)
})

const previewSizeClass = computed(() => {
  if (props.variant === 'avatar') {
    return props.size === 'sm' ? 'w-12 h-12' : props.size === 'lg' ? 'w-24 h-24' : 'w-16 h-16'
  }
  return props.size === 'sm' ? 'w-20 h-20' : props.size === 'lg' ? 'w-40 h-40' : 'w-28 h-28'
})

const { isDragging, handleDragOver, handleDragEnter, handleDragLeave, handleDrop } = useImageDropUpload({
  disabled: () => props.disabled || uploading.value,
  onFiles: (files) => uploadFile(files[0]),
})

const triggerFileInput = () => {
  if (props.disabled || uploading.value) return
  fileInput.value?.click()
}

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

const uploadFile = async (file: File) => {
  if (!file.type.startsWith('image/')) {
    error.value = '请选择图片文件'
    toast.showToast(error.value, 'error')
    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 result = await parseApiResponse<{ fileUrl: string }>(await authFetch(`${API_BASE}/admin/attachments/upload`, {
      method: 'POST',
      headers: {},
      body: formData
    }))
    imageUrl.value = result.fileUrl
    toast.showToast('图片上传成功', 'success')
  } catch (err: any) {
    error.value = err.message || '上传失败，请重试'
    toast.showToast(error.value, 'error')
  } finally {
    uploading.value = false
  }
}

const clearImage = () => {
  if (props.disabled) return
  imageUrl.value = ''
  if (fileInput.value) fileInput.value.value = ''
}

const openLibraryModal = () => {
  if (props.disabled) return
  showLibraryModal.value = true
}

const handleLibrarySelect = (urls: string[]) => {
  if (urls.length > 0) {
    imageUrl.value = urls[0]
    toast.showToast('图片选择成功', 'success')
  }
}
</script>

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