<script setup lang="ts">
import { ref, watch } from 'vue'
import { Plus } from '@element-plus/icons-vue'
import { UpFileToken } from '@/api/public/index'
import { ElMessage, genFileId, ElLoading } from 'element-plus'
import { GlobalStore } from '@/stores/index'
import type { UploadProps, UploadRawFile, UploadUserFile, UploadFile, UploadFiles } from 'element-plus'

interface FileListType {
  url?: string
  name?: string | number
}

interface ProTableProps {
  isImg?: boolean // 是否只能上传图片
  disabled?: boolean
  limit: number
  modelValue: string | string[]
}

const upload = ref()
const globalStore = GlobalStore()
const dialogImageUrl = ref('')
const dialogVisible = ref(false)
const uploadData = {
  token: '',
  key: ''
}
let loadingInstance: any = null
const emit = defineEmits<{ (event: 'update:modelValue', value: string | string[]): void }>()

// 图片查看 放大
const handlePictureCardPreview = async (file: any) => {
  dialogImageUrl.value = file.url as string
  dialogVisible.value = true
}
// 图片上传之前
const beforeUpload = async (file: any) => {
  let reg = /^image/g
  if (isImg.value && !reg.test(file.type)) {
    ElMessage.error('必须上传图片!!')
    return
  }
  loadingInstance = ElLoading.service({
    lock: true,
    text: 'Loading',
    background: 'rgba(0, 0, 0, 0.7)'
  }) // 加载蒙版
  let suffix = file.type.split('/')[1]
  const res: any = await UpFileToken({ User_tokey: globalStore.GET_User_tokey, T_suffix: suffix })
  uploadData.token = res.Data
  uploadData.key = file.name
}
// 图片上传超出界限
const handleExceed: UploadProps['onExceed'] = (files: any, uploadFiles: UploadUserFile[]) => {
  console.log(files, uploadFiles)

  upload.value.clearFiles()
  const file = files[0] as UploadRawFile
  file.uid = genFileId()
  upload.value.handleStart(file)
  upload.value.submit()
}
// 图片上传成功
const onSuccess = (response: any, uploadFile: UploadFile, uploadFiles: UploadFiles) => {
  let ERPOSS = import.meta.env.VITE_BZD_ERPOSS_APP_API
  if (limit.value === 1) {
    emit('update:modelValue', ERPOSS + response.key)
  } else {
    let keys = uploadFiles.map((item: any) => ERPOSS + item.response.key)
    emit('update:modelValue', keys)
  }
  ElMessage.success('图片上传成功!!')
  loadingInstance.close()
}
// 图片上传失败
const onError = () => {
  ElMessage.error('图片上传失败!!')
}
// 图片移除
const handleRemove: UploadProps['onRemove'] = (uploadFile: any, uploadFiles: UploadFiles) => {
  if (limit.value === 1) {
    emit('update:modelValue', '')
  } else {
    let keys = uploadFiles.map((item: any) => {
      if (item.response.key !== uploadFile.response.key) {
        return item.response.key
      }
    })
    emit('update:modelValue', keys)
  }
}

// 接受父组件参数，配置默认值
const props = withDefaults(defineProps<ProTableProps>(), {
  disabled: false
  // modelValue: ''
})

const fileList = ref<FileListType[]>([])
const isImg = ref<boolean>(props.isImg)
const limit = ref<number>(props.limit)

watch(
  () => props.modelValue,
  pre => {
    if (pre && fileList.value.length !== limit.value) {
      if (limit.value === 1) {
        fileList.value.push({
          url: pre as string,
          name: genFileId()
        })
      } else {
        ;(pre as string[]).forEach((item: string) => {
          fileList.value.push({
            url: item,
            name: genFileId()
          })
        })
      }
    }
  }
)

const clearfileList = () => {
  fileList.value = []
}
defineExpose({
  clearfileList
})
</script>

<template>
  <div>
    <el-upload
      ref="upload"
      :disabled="disabled"
      v-model:file-list="fileList"
      action="https://up-z2.qiniup.com"
      list-type="picture-card"
      :limit="limit"
      :auto-upload="true"
      :before-upload="beforeUpload"
      :on-success="onSuccess"
      :on-error="onError"
      :on-exceed="handleExceed"
      :on-remove="handleRemove"
      :on-preview="handlePictureCardPreview"
      :data="uploadData"
    >
      <el-icon><Plus /></el-icon>
    </el-upload>
    <el-dialog v-model="dialogVisible">
      <img w-full :src="dialogImageUrl" class="full-img" alt="Preview Image" />
    </el-dialog>
  </div>
</template>

<style scoped>
.full-img {
  width: 100%;
  height: 100%;
}
</style>
