<!-- 编辑弹窗 -->
<template>
    <ele-modal :width="940" v-model="visible" title="上传图片">
        <el-form :model="form" label-width="auto">
            <el-form-item>
                <div class="flex justify-between items-center w-full">
                    <div class="flex items-center flex-1">
                        <el-checkbox
                            v-model="checkAll"
                            @change="handleCheckAllChange"
                        >
                            全选
                        </el-checkbox>

                        <el-text style="margin: 0 30px"
                            >共有{{ form.images.length }}条</el-text
                        >

                        <el-radio-group v-model="form.coverImport">
                            <el-radio :value="1">相同文件名覆盖</el-radio>
                            <el-radio :value="0">相同文件名忽略</el-radio>
                        </el-radio-group>
                    </div>
                    <div>
                        <el-button type="danger" @click="handleBatchDelete"
                            >删除</el-button
                        >
                        <el-button type="primary" @click="handleSubmit"
                            >提交</el-button
                        >
                    </div>
                </div>
            </el-form-item>
            <el-form-item>
                <el-checkbox-group v-model="checkList" class="flex flex-wrap">
                    <el-upload
                        class="upload-image"
                        ref="uploadRef"
                        v-model:file-list="form.images"
                        list-type="picture-card"
                        :auto-upload="false"
                        :show-file-list="false"
                        multiple
                        accept="image/*"
                    >
                        <div class="flex flex-col items-center">
                            <el-icon :size="24"><Plus /></el-icon>
                            <el-text type="info" style="margin-top: 20px"
                                >上传图片</el-text
                            >
                        </div>
                    </el-upload>
                    <div
                        class="flex flex-wrap pos-relative image-item"
                        v-for="item in form.images"
                    >
                        <el-checkbox :value="item.uid" class="checkbox-item" />
                        <el-image
                            style="width: 98px; height: 98px"
                            :src="item.url"
                            fit="cover"
                        />
                        <div
                            class="mask-error flex items-center justify-center"
                            v-if="item.error"
                        >
                            <el-text type="danger" size="small">{{
                                item.error
                            }}</el-text>
                        </div>
                    </div>
                </el-checkbox-group>
            </el-form-item>
        </el-form>
    </ele-modal>
</template>

<script setup>
    import { ref, reactive, nextTick } from 'vue';
    import ImageUpload from '@/components/ImageUpload/index.vue';
    import { Plus } from '@element-plus/icons-vue';
    import request from '@/utils/request';
    import { ElMessage } from 'element-plus';

    const form = reactive({
        images: [],
        coverImport: 1
    });
    const emit = defineEmits(['done']);
    /** 弹窗是否打开 */
    const visible = defineModel({ type: Boolean });
    /** 关闭弹窗 */
    const handleCancel = () => {
        visible.value = false;
    };

    //选择的文件
    const checkList = ref([]);

    /** 弹窗打开事件 */
    const handleOpen = () => {
        visible.value = true;
        nextTick(() => {
            checkAll.value = false;
            checkList.value = [];
            form.images = [];
        });
    };

    const uploadRef = ref(null);
    //批量删除
    function handleBatchDelete() {
        let checkFiles = form.images.filter((item) =>
            checkList.value.includes(item.uid)
        );
        checkFiles.forEach((file) => {
            uploadRef.value?.handleRemove(file);
        });
    }

    const checkAll = ref(false);
    function handleCheckAllChange() {
        checkList.value = checkAll.value
            ? form.images.map((item) => item.uid)
            : [];
    }

    // 提交
    async function handleSubmit() {
        const { results, failedImages } = await processUploadQueue([
            ...form.images
        ]);
        form.images = failedImages;
        ElMessage.success(
            `上传成功${results.length}张，失败${failedImages.length}张`
        );
        emit('done', results);
    }

    //上传队列
    async function processUploadQueue(images, maxUploadNum = 6) {
        const queue = [];
        const results = [];
        const failedImages = [];

        // 创建一个函数来添加新的上传任务到队列中
        function enqueue(image) {
            const formData = new FormData();
            formData.append('file', image.raw); //文件
            formData.append('coverImport', form.coverImport);

            let uploadImage = request
                .post('/book/bookInfo/importCover', formData, {
                    showTips: false
                })
                .then((res) => {
                    if (res.data.code == 200) {
                        results.push(res);
                    } else {
                        image.status = 'fail';
                        image.error = res.data.msg;
                        failedImages.push(image);
                    }
                })
                .finally(() => {
                    // 当一个上传任务完成时，从队列中移除它，并尝试添加新的任务
                    queue.shift();
                    if (images.length > 0 && queue.length < maxUploadNum) {
                        enqueue(images.shift());
                    }
                });
            queue.push(uploadImage);
        }

        // 初始化队列
        for (let i = 0; i < Math.min(images.length, maxUploadNum); i++) {
            enqueue(images.shift());
        }

        // 等待所有上传任务完成
        await Promise.all(queue);

        return { results, failedImages };
    }

    defineExpose({
        handleOpen
    });
</script>

<style lang="scss">
    .image-item {
        margin-right: 10px;
        margin-bottom: 10px;
        position: relative;
        border-radius: 6px;
        border: 1px solid #e4e7ed;
        .checkbox-item {
            position: absolute;
            top: -8px;
            left: 0;
        }

        .mask-error {
            width: 100%;
            height: 24px;
            background-color: rgba(255, 0, 0, 0.1);
            position: absolute;
            overflow: hidden;
            bottom: 0;
            left: 0;
        }
    }
</style>
