<template>
    <ele-modal
        :width="460"
        :title="title"
        :body-style="{ paddingTop: '8px' }"
        v-model="visible"
    >
        <div class="flex mb-2">
            <div class="text-sm">请先下载'{{ templateName }}':</div>
            <el-button
                @click="downloadTemplate"
                link
                type="primary"
            >下载{{ templateName }}</el-button>
        </div>

        <div class="flex flex-col mb-2">
            <div class="text-sm text-yellow-500">{{ instructionTitle }}：</div>
            <div
                v-for="(item, index) in instructions"
                :key="index"
                class="text-sm"
            >
                {{ index + 1 }}.{{ item }}
            </div>
        </div>
        <div v-loading="loading" class="user-import-upload">
            <el-upload
                v-model:file-list="fileList"
                ref="uploadRef"
                action=""
                accept=".xls,.xlsx"
                :before-upload="doUpload"
                :auto-upload="false"
                :limit="1"
                :on-exceed="handleExceed"
            >
                <el-button type="primary" class="mr-2">选择文件</el-button>
                <ele-text type="placeholder">只能上传 xls、xlsx 文件</ele-text>
            </el-upload>
        </div>

        <template #footer>
            <el-button @click="visible = false">关闭</el-button>
            <el-button type="primary" @click="handleSumbit" :loading="loading"
                >导入</el-button
            >
        </template>
    </ele-modal>
</template>

<script setup>
    import { ref } from 'vue';
    import { genFileId } from 'element-plus';
    import { EleMessage } from 'ele-admin-plus/es';
    import { downloadOssLink } from '@/utils/common';
    import request from '@/utils/request';

    const props = defineProps({
        title: { type: String, default: '导入' },
        templateName: { type: String, default: '导入模板' },
        templateUrl: { type: String, required: true },
        uploadUrl: { type: String, required: true },
        instructionTitle: { type: String, default: '使用说明' },
        instructions: {
            type: Array,
            default: () => [
                '支持通过导入来批量操作',
                '导入文件第一行需与模版完全一致'
            ]
        }
    });

    const emit = defineEmits(['done']);

    const visible = defineModel({ type: Boolean });

    const loading = ref(false);

    const uploadRef = ref(null);
    const fileList = ref([]);

    function handleExceed(files) {
        uploadRef.value?.clearFiles();
        const file = files[0];
        file.uid = genFileId();
        uploadRef.value?.handleStart(file);
    }

    function downloadTemplate() {
        downloadOssLink(props.templateUrl, props.templateName);
    }

    async function importFile(file) {
        const formData = new FormData();
        formData.append('file', file);

        const res = await request.post(props.uploadUrl, formData);
        if (res.data.code === 200) {
            return res.data;
        }
        return Promise.reject(new Error(res.data.msg));
    }

    const handleSumbit = () => {
        if (fileList.value.length === 0) {
            EleMessage.error('请选择文件');
            return;
        }
        loading.value = true;
        let file = fileList.value[0];
        importFile(file.raw)
            .then((res) => {
                loading.value = false;
                EleMessage.success('操作成功,请前往导出记录下载');
                visible.value = false;
                emit('done');
            })
            .catch((e) => {
                loading.value = false;
            });
    };

    const doUpload = (file) => {
        if (
            ![
                'application/vnd.ms-excel',
                'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
            ].includes(file.type)
        ) {
            EleMessage.error('只能选择 excel 文件');
            return false;
        }
        if (file.size / 1024 / 1024 > 10) {
            EleMessage.error('大小不能超过 10MB');
            return false;
        }
        return false;
    };
</script>
