<template>
    <el-upload
        ref="uploadRef" :accept="accept" :action="api + action" :before-upload="beforeUpload"
        :data="uploadData" :disabled="uploadDisabled" :headers="getHeader()" :limit="1" :on-error="uploadError"
        :on-exceed="uploadExceed" :on-progress="uploadprogress" :on-success="uploadSuccess"
        :show-file-list="false" class="hc-file-upload-box"
    >
        <slot />
    </el-upload>
</template>

<script setup>
import { onMounted, ref, watch } from 'vue'
import { getHeader } from 'hc-vue3-ui'
import { deepClone, getObjValue, isFileSize } from 'js-fast-way'
import { genFileId } from 'element-plus'

const props = defineProps({
    datas: {
        type: Object,
        default: () => ({}),
    },
    api: {
        type: String,
        default: '/api/blade-resource/oss/endpoint/',
    },
    action: {
        type: String,
        default: 'upload-file',
    },
    accept: {
        type: String,
        default: 'image/png,image/jpg,image/jpeg,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/pdf,.doc,.docx,application/msword',
    },
    size: {
        type: Number,
        default: 60,
    },
})

//事件
const emit = defineEmits(['change', 'progress'])
//变量
const uploadRef = ref(null)
const uploadData = ref(props.datas)
const uploadDisabled = ref(false)

//监听
watch(() => [
    props.datas,
], ([datas]) => {
    uploadData.value = datas
})

//渲染完成
onMounted(() => {
    beforeFileNum.value = 0
    finishFileNum.value = 0
    errorFileNum.value = 0
})

//上传前
const beforeFileNum = ref(0)
const beforeUpload = async (file) => {
    if (isFileSize(file?.size, props.size)) {
        beforeFileNum.value++
        return true
    } else {
        beforeFileNum.value = 0
        window?.$message?.warning(`文件大小, 不能过${props.size}M!`)
        return false
    }
}

//超出限制时
const uploadExceed = (files) => {
    uploadRef.value?.clearFiles()
    const file = files[0]
    file.uid = genFileId()
    uploadRef.value?.handleStart(file)
}

//上传中
const uploadprogress = () => {
    uploadDisabled.value = true
    emit('progress', true)
}

//上传完成
const finishFileNum = ref(0)
const uploadSuccess = (response, uploadFile, uploadFiles) => {
    finishFileNum.value++
    if (beforeFileNum.value === finishFileNum.value) {
        const fileList = getUploadFile(deepClone(uploadFiles))
        uploadClearFiles()
        emit('change', { type: 'success', fileList })
        emit('progress', false)
    }
}

//上传失败
const errorFileNum = ref(0)
const uploadError = (error, uploadFile, uploadFiles) => {
    errorFileNum.value++
    window?.$message?.error('上传失败')
    const num = finishFileNum.value + errorFileNum.value
    if (beforeFileNum.value === num) {
        const fileList = getUploadFile(deepClone(uploadFiles))
        uploadClearFiles()
        emit('change', { type: 'error', fileList })
        emit('progress', false)
    }
}

const uploadClearFiles = () => {
    finishFileNum.value = 0
    beforeFileNum.value = 0
    errorFileNum.value = 0
    uploadDisabled.value = false
    uploadRef.value?.clearFiles()
}

//获取文件
const getUploadFile = (fileList) => {
    let fileArr = []
    for (let i = 0; i < fileList.length; i++) {
        const item = getObjValue(fileList[i]?.response?.data)
        fileArr.push(item)
    }
    return fileArr
}
</script>

<style lang="scss">
.hc-file-upload-box .el-upload-list .el-upload-list__item {
    .el-upload-list__item-status-label, .el-icon--close-tip {
        display: none;
    }
}
</style>
