<template>
    <view v-if="custom">
        <up-upload @after-read="afterRead" :deletable="!disabled" @delete="deletePic"
            :max-count="disabled ? fileList.length : maxCount" :accept="accept" multiple @clickPreview="clickPreview">
            <slot />
        </up-upload>
    </view>
    <up-upload v-else :fileList="fileList" @after-read="afterRead" :deletable="!disabled" @delete="deletePic"
        :max-count="disabled ? fileList.length : maxCount" :accept="accept" multiple @clickPreview="clickPreview" />
</template>

<script setup>
import { ref, reactive, defineProps, defineEmits, getCurrentInstance, onUnmounted } from 'vue'
const emit = defineEmits(['uploadCallback', 'startUploading'])
const props = defineProps({
    accept: {
        type: String,
        default: "image"
    },
    maxCount: {
        type: [String, Number],
        default: 99
    },
    uploadCallback: {
        type: Function
    },
    startUploading: {
        type: Function
    },
    fileList: {
        type: Array,
        default: reactive([])
    },
    usetype: {
        type: String,
        default: 'default'
    },
    ownertable: {
        type: String,
        default: 'temporary'
    },
    ownerid: {
        type: [String, Number],
        default: 1
    },
    disabled: {
        type: Boolean,
        default: false
    },
    custom: {
        type: Boolean,
        default: false
    }
})
const { $Http } = getCurrentInstance().proxy;
const deleteList = reactive([]); // 用于存储待删除的文件列表

const clickPreview = (e) => {
    uni.previewImage({
        urls: props.fileList.map(v => v.url),
        current: e.url,
        loop: true,
    })
}

// 文件读取后处理
const afterRead = ({ file }) => {
    emit('startUploading', file);
    file.forEach(v => {
        // #ifdef H5
        getArrayBuffer(v).then(data => {
            data.data.url = v.url;
            console.log("data.data", data.data)
            handleUploadFile(requestType(v), data.data)
            props.fileList.push({
                ...v,
                status: 'uploading',
                message: '上传中',
            });
        })
        // #endif

        // #ifndef H5
        uni.getFileSystemManager().readFile({
            filePath: v.url,
            success: data => {
                data.data.url = v.url;
                handleUploadFile(requestType(v), data.data)
                props.fileList.push({
                    ...v,
                    status: 'uploading',
                    message: '上传中',
                });
            },
            fail: console.error
        })
        // #endif
    })
}

// 获取文件类型信息
const requestType = (file) => {
    let ext = ''

    // #ifdef H5
    ext = file.name.substring(file.name.lastIndexOf(".") + 1)
    // #endif

    // #ifndef H5
    ext = file.type?.split("/")[1] ||
        file.url.substring(file.url.lastIndexOf(".") + 1) ||
        file.name.substring(file.name.lastIndexOf(".") + 1)
    // #endif

    return {
        "classname": "system.attachment.huawei.OBS",
        "method": "getFileName",
        "content": {
            "filename": `${Date.now() + file.size}.${ext}`,
            "filetype": ext,
            "parentid": uni.getStorageSync('siteP').appfolderid
        }
    }
}

// 处理文件上传
const handleUploadFile = (file, data) => {
    $Http.basic(file).then(res => {
        console.log("上传文件成功", res)
        if (res.msg == "成功") {
            uploadFile(res.data, data)
        } else {
            uni.showToast({
                title: `${file.content.filename}上传失败`,
                icon: "none"
            })
        }
    })
}

// 获取ArrayBuffer (H5专用)
const getArrayBuffer = (file) => {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest()
        xhr.open('GET', file.url, true)
        xhr.responseType = 'blob'
        xhr.onload = function () {
            if (this.status === 200) {
                const myBlob = this.response
                const files = new File(
                    [myBlob],
                    file.name,
                    { type: file.type },
                )
                const reader = new FileReader()
                reader.readAsArrayBuffer(files)
                reader.onload = () => resolve({
                    data: reader.result
                })
                reader.onerror = error => reject(error)
            } else {
                reject(`文件加载失败: ${this.status}`)
            }
        }
        xhr.onerror = () => reject('网络请求失败')
        xhr.send()
    })
}

// 上传文件到服务器
const uploadFile = (res, data) => {
    uni.request({
        url: res.uploadurl,
        method: "PUT",
        data,
        header: { 'Content-Type': 'application/octet-stream' },
        success: () => {
            $Http.basic({
                "classname": "system.attachment.huawei.OBS",
                "method": "uploadSuccess",
                "content": { "serialfilename": res.serialfilename }
            }).then(s => {
                console.log("文件上传反馈", s)
                handleFileLink([{
                    attachmentid: s.data.attachmentids[0],
                    url: data.url
                }], "temporary", 1, props.usetype)
            }).catch(console.error)
        },
        fail: console.error
    })
}

function handleFileLink(list, ownertable = "temporary", ownerid = 1, usetype = 'default', resolve = () => { }) {
    if (list.length == 0) return resolve(true);
    let content = {
        ownertable,
        ownerid,
        usetype,
        attachmentids: list.map(v => v.attachmentid),
        siteid: uni.getStorageSync("userMsg").siteid
    }
    $Http.basic({
        "classname": "system.attachment.Attachment",
        "method": "createFileLink",
        content
    }).then(res => {
        console.log('跟进记录绑定附件', res)
        resolve(res.code == '1')
        if (res.code != '1') return uni.showToast({
            title: res.msg,
            icon: "none"
        })
        list.forEach(v => {
            const file = props.fileList.find(s => v.url === s.url);
            delete file.status;
            delete file.message;

            if (file) {
                Object.assign(file, res.data.find(s => s.attachmentid === v.attachmentid));
            }
        });
        emit('uploadCallback', { fileList: props.fileList, attachmentids: content.attachmentids })
    })
}

// 保存所有的附件绑定到表上，有在上传的文件不能保存
const isUploading = (showToast = true) => {
    let res = props.fileList.some(file => file.status === 'uploading');
    if (res && showToast) uni.showToast({
        title: '文件正在上传中，请稍后再试',
        icon: 'none'
    });
    return res
}

// 保存接口 接受数据调用handleFileLink
const saveFileLinks = (ownertable, ownerid, usetype = 'default') => {
    // 如果有待删除的文件，先删除
    deleteList.length && deleteFile(deleteList);
    return new Promise((resolve, reject) => {
        const list = props.fileList;
        console.log("list", list)
        if (list.length) {
            return handleFileLink(list, ownertable, ownerid, usetype, resolve);
        } else {
            resolve(true)
        }
    })
}

function deletePic({ file, index, name }) {
    uni.showModal({
        cancelText: '取消',
        confirmText: '删除',
        content: '是否确定删除该文件？',
        title: '提示',
        success: ({ confirm }) => {
            if (confirm) {
                console.log("删除文件", file);
                if (file.ownertable == 'temporary') {
                    // 临时文件直接删除
                    deleteFile([file]).then(res => {
                        if (res) {
                            props.fileList.splice(index, 1);
                            emit('uploadCallback', { fileList: props.fileList });
                        }
                    })
                } else {
                    deleteList.push(file)
                    props.fileList.splice(index, 1);
                    emit('uploadCallback', { fileList: props.fileList })
                }
            }
        },
    })
}

// 直接删除文件
const deleteFile = (arr) => {
    return new Promise((resolve, reject) => {
        let list = arr.filter(file => file.linksid);
        if (list.length) {
            $Http.basic({
                "classname": "system.attachment.Attachment",
                "method": "deleteFileLink",
                "content": {
                    linksids: list.map(v => v.linksid),
                }
            }).then(res => {
                console.log("删除文件", res);
                resolve(res.code == 1)
                if (res.code != 1) uni.showToast({
                    title: res.msg,
                    icon: "none"
                })
            })
        } else {
            resolve(true)
        }
    })
}

// 清空临时文件 ownertable == 'temporary'
const clearTemporaryFiles = (arr = props.fileList) => {
    let list = arr.filter(file => file.ownertable == 'temporary' && file.linksid);
    if (list.length) $Http.basic({
        "classname": "system.attachment.Attachment",
        "method": "deleteFileLink",
        "content": {
            linksids: list.map(v => v.linksid),
        }
    }).then(res => {
        console.log("清空临时文件", res);
    })
}

// 在页面销毁的时候 自动清空所有的临时文件
onUnmounted(() => {
    clearTemporaryFiles();
})

defineExpose({ isUploading, handleFileLink, saveFileLinks, deleteFile })
</script>