<template>
  <view>
    <up-upload
      v-if="isUpdate"
      :file-list="fileList"
      :accept="accept"
      multiple
      :size-type="['original', 'compressed']"
      :max-count="maxCount"
      :width="width"
      :height="height"
      :preview-full-image="true"
      :disabled="disabled"
      @delete="deletePic"
      @after-read="afterRead"
    >
    </up-upload>
    <u-album v-else multiple-size="85" single-size="85" :urls="imgs" row-count="4" />
  </view>
</template>

<script setup>
import { ref, reactive, watch, onMounted } from 'vue'
import { getBaseUrl, getImgBaseUrl } from '@/defaultBaseUrl'

const props = defineProps({
  modelValue: { type: [Array, String], default: '' },
  isUpdate: { type: Boolean, default: true },
  disabled: { type: Boolean, default: false },
  accept: { type: String, default: 'image' },
  width: { type: String, default: '80px' },
  height: { type: String, default: '80px' },
  maxCount: { type: Number, default: 20 },
  returnAsString: { type: Boolean, default: true }
})

const emit = defineEmits(['update:modelValue'])

const fileList = ref([])
const imgs = ref([])
const uploadConfig = reactive({
  baseURL: getBaseUrl(),
  imgBaseURL: getImgBaseUrl(),
  header: { Authorization: 'Bearer ' + uni.getStorageSync('token') }
})

// 同步外部值到组件
watch(
  () => props.modelValue,
  newVal => {
    if (!newVal) return (fileList.value = [])
    const urls = Array.isArray(newVal) ? newVal : newVal.split(',')
    imgs.value = urls.map(url => url.previewUrl)
    fileList.value = urls.map(url => ({
      url: url.url,
      status: 'success',
      name: url.name,
      id: url.id,
      message: ''
    }))
  },
  { immediate: true }
)

const deletePic = event => {
  fileList.value.splice(event.index, 1)
  updateParent(fileList.value)
}

const afterRead = async event => {
  const files = [].concat(event.file)
  const initialLength = fileList.value.length

  // 添加上传状态
  fileList.value.push(
    ...files.map(file => ({
      ...file,
      status: 'uploading',
      message: '上传中'
    }))
  )

  try {
    for (let i = 0; i < files.length; i++) {
      const result = await uploadFile(files[i])
      const index = initialLength + i
      console.log(files[i])

      fileList.value[index] = {
        status: 'success',
        url: result.url,
        name: result.name,
        id: result.id
      }
    }
  } catch (error) {
    console.error('Upload failed:', error)
    // 回滚失败的上传
    fileList.value.splice(initialLength, files.length)
  } finally {
    updateParent(fileList.value)
  }
}

const uploadFile = file => {
  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url: `${uploadConfig.baseURL}/infra/file/upload-with-return`,
      filePath: file.url,
      name: 'file',
      header: uploadConfig.header,
      formData: { encrypt: false },
      success: res => {
        if (res.statusCode === 200) {
          let result = JSON.parse(res.data)
          if (result.code === 0) {
            resolve(result.data)
          } else {
            reject(new Error(result.msg))
          }
        } else {
          reject(new Error(res.data))
        }
      },
      fail: reject
    })
  })
}

const formatValue = fileList => {
  // 去掉 imgBaseURL 后的部分
  const baseUrlLength = uploadConfig.imgBaseURL.length
  return props.returnAsString
    ? fileList.map(item => item.url.slice(baseUrlLength)).join(',')
    : fileList.map(item => item.url.slice(baseUrlLength))
}
const updateParent = fileList => {
  emit('update:modelValue', fileList)
}
</script>

<style lang="scss" scoped>
:deep(.u-upload__wrap__preview) {
  margin: 0;
}
</style>
