<template>
  <div class="file-uploader">
    <van-uploader
      :max-count="1"
      :after-read="handleAfterRead"
      :preview-size="previewSize"
      :show-upload="!modelValue"
      :disabled="uploading"
    >
      <slot v-if="!modelValue">
        <div class="upload-placeholder" :style="{ width: previewSize + 'px', height: previewSize + 'px' }">
          <van-icon name="photograph" class="upload-icon" />
          <div class="upload-text">{{ uploading ? '上传中...' : placeholder }}</div>
        </div>
      </slot>
    </van-uploader>
    <div v-if="modelValue" class="preview-wrapper">
      <van-image
        :src="modelValue"
        :preview-src-list="[modelValue]"
        class="preview-image"
        :width="previewSize"
        :height="previewSize"
        fit="cover"
        radius="6"
        preview
      />
      <van-icon v-if="showDelete" name="cross" class="delete-btn" @click.stop="handleDelete" />
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { Toast } from 'vant'
import { uploadFile } from '@/api/common'

const props = defineProps({
  modelValue: { type: String, default: '' },
  previewSize: { type: [Number, String], default: 100 },
  placeholder: { type: String, default: '点击上传' },
  showDelete: { type: Boolean, default: true }
})

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

const uploading = ref(false)

async function handleAfterRead(file) {
  uploading.value = true
  try {
    const fileObj = file.file
    const res = await uploadFile(fileObj)
    // 根据响应结构获取 URL，请根据实际返回调整
    const url = res? res.fileName : ''
    if (url) {
      emit('update:modelValue', url)
      emit('success', url)
    } else {
      throw new Error('上传失败')
    }
  } catch (err) {
    console.error('上传失败:', err)
    Toast('上传失败，请重试')
    emit('error', err)
  } finally {
    uploading.value = false
  }
}

function handleDelete() {
  emit('update:modelValue', '')
  emit('delete')
}
</script>

<style lang="scss" scoped>
.file-uploader {
  display: inline-block;

  :deep(.van-uploader) {
    display: block;
  }

  :deep(.van-uploader__wrapper) {
    display: block;
  }

  :deep(.van-uploader__preview) {
    margin: 0;
  }
}

::v-deep .upload-placeholder {
  background: #fff;
  border: 1px dashed #d1d5db;
  border-radius: 6px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 135px !important;
  height: 135px !important;

  .upload-icon {
    font-size: 28px;
    color: #9ca3af;
  }

  .upload-text {
    font-size: 12px;
    color: #6b7280;
  }
}

.preview-wrapper {
  position: relative;
  display: inline-block;

  .preview-image {
    display: block;
  }

  .delete-btn {
    position: absolute;
    top: -6px;
    right: -6px;
    width: 20px;
    height: 20px;
    background: rgba(0, 0, 0, 0.6);
    border-radius: 50%;
    color: #fff;
    font-size: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
  }
}
</style>
