<script setup lang="ts" name="UploadImage">
import { ref, watch, defineProps, defineEmits } from 'vue'
import {useUserStore} from '../../store'
const userStore = useUserStore()
// 定义组件 props（显式声明 modelValue 为数组）
const props = withDefaults(defineProps<{
  maxCount?: number 
  multiple?: boolean 
  accept?: string
  modelValue: UploaderFileListItem[]
}>(), {
  maxCount: 9,
  multiple: true,
  accept: 'image/*'
})

// 定义双向绑定事件
const emit = defineEmits(['update:modelValue'])

// 文件列表（初始化为空数组）
const fileList = ref<UploaderFileListItem[]>([])

// 监听父组件传入的 modelValue 变化（校验数组类型）
watch(
  () => props.modelValue, 
  (newVal) => {
    if (Array.isArray(newVal)) {
      fileList.value = JSON.parse(JSON.stringify(newVal))
    } else {
      fileList.value = []
      console.warn('父组件传递的 v-model 非数组，已重置为空数组')
    }
  }, 
  { deep: true }
)

// 选择图片
const chooseImage = async () => {
  try {
    const chooseRes = await uni.chooseImage({
      count: props.multiple ? props.maxCount : 1,
      sourceType: ['album', 'camera'],
      sizeType: ['compressed'],
      extension: ['.png', '.jpg', '.jpeg']
    })

    // 处理选中的文件（确保 tempFiles 是数组）
    const tempFiles = Array.isArray(chooseRes.tempFiles) 
      ? chooseRes.tempFiles.map((file: any) => ({
          ...file,
          status: 'uploading',
          message: '上传中...',
          url: '',
          name: ''
        }))
      : []

    // 更新文件列表
    fileList.value = [...fileList.value, ...tempFiles]

    // 开始上传
    uploadFiles(tempFiles)
  } catch (err) {
    console.error('选择图片失败:', err)
  }
}

// 上传文件列表
const uploadFiles = async (files: any[]) => {
  for (const file of files) {
    try {
      const res = await uploadToServer(file)
      const index = fileList.value.findIndex(item => item.path === file.path)
      if (index !== -1) {
        fileList.value[index] = {
          ...fileList.value[index],
          status: 'done',
          message: '',
          url: res.data.url,
          name: res.data.name
        }
      }
    } catch (err) {
      const index = fileList.value.findIndex(item => item.path === file.path)
      if (index !== -1) {
        fileList.value[index] = {
          ...fileList.value[index],
          status: 'failed',
          message: '上传失败'
        }
      }
    }
  }
  emit('update:modelValue', fileList.value)
}

// 实际上传到服务器的方法
const uploadToServer = (file: any) => {
  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url: 'https://demo.docmis.cn:21143/dl-prod-api/file/upload',
      filePath: file.path,
      name: 'file',
      method: 'POST',
      header: { 'Content-Type': 'multipart/form-data','Authorization': 'Bearer ' + userStore.accessToken},
      success: (res) => {
        if (res.statusCode === 200) {
          const data = JSON.parse(res.data)
          resolve(data)
        } else {
          reject(new Error(`上传失败，状态码：${res.statusCode}`))
        }
      },
      fail: (err) => reject(err)
    })
  })
}

// 删除文件
const deleteFile = (index: number) => {
  fileList.value.splice(index, 1)
  emit('update:modelValue', fileList.value)
}
</script>

<template>
  <view class="upload-container">
    <view class="image-list" style="display: flex;flex-wrap: wrap;">
      <!-- 关键：仅当 fileList 是数组时遍历 -->
      <template v-if="Array.isArray(fileList)">
        <view 
          v-for="(item, index) in fileList" 
          :key="index" 
          class="image-item"
        >
          <image 
            v-if="item.status !== 'uploading'" 
            :src="item.url || item.path" 
            mode="aspectFill" 
            class="preview-img"
            @tap="uni.previewImage({ current: index, urls: fileList.map(i => i.url || i.path) })"
          />
          <view v-else class="upload-loading">
            <text class="loading-text">{{ item.message }}</text>
          </view>

          <view class="status-tag" v-if="item.status !== 'done'">
            <text :class="{ 'uploading': item.status === 'uploading', 'failed': item.status === 'failed' }">
              {{ item.message }}
            </text>
          </view>

          <view class="delete-btn" @tap="deleteFile(index)" v-if="item.status !== 'uploading'">
            <text class="delete-icon">×</text>
          </view>
        </view>
      </template>
      <view v-else class="empty-tip">无图片数据</view>
    </view>

    <view 
      class="upload-btn" 
      @tap="chooseImage"
      :class="{ 'disabled': fileList.length >= props.maxCount }"
    >
      <text class="upload-icon">+</text>
      <text class="upload-tip">上传图片</text>
    </view>
  </view>
</template>

<style lang="less" scoped>
.upload-container {
  padding: 20rpx;
}

.image-list {
  display: flex;
  flex-wrap: wrap;
  gap: 20rpx;
}

.image-item {
  position: relative;
  width: 200rpx;
  height: 200rpx;
  border-radius: 8rpx;
  overflow: hidden;
}

.preview-img {
  width: 100%;
  height: 100%;
}

.upload-loading {
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
}

.loading-text {
  color: #fff;
  font-size: 24rpx;
}

.status-tag {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  padding: 4rpx;
  text-align: center;
  font-size: 20rpx;
  background: rgba(0, 0, 0, 0.5);
  color: #fff;

  .uploading {
    color: #1890ff;
  }

  .failed {
    color: #ff4d4f;
  }
}

.delete-btn {
  position: absolute;
  top: -10rpx;
  right: -10rpx;
  width: 40rpx;
  height: 40rpx;
  background: #ff4d4f;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;

  .delete-icon {
    color: #fff;
    font-size: 28rpx;
    line-height: 1;
  }
}

.upload-btn {
  width: 200rpx;
  height: 200rpx;
  border: 2rpx dashed #ddd;
  border-radius: 8rpx;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #999;
  font-size: 24rpx;
  cursor: pointer;

  &.disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }

  .upload-icon {
    font-size: 60rpx;
    margin-bottom: 8rpx;
  }
}

.empty-tip {
  width: 200rpx;
  height: 200rpx;
  border: 2rpx dashed #ddd;
  border-radius: 8rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #999;
  font-size: 24rpx;
}
</style>