<template>
    <div class="import-create-wrap">
        <BaseImport @importFinish="onImportFinish"></BaseImport>
        <Modal v-model="importStatus" title="导入试卷" width="1200" :loading="modalLoading" @on-ok="saveTestPaper" :mask-closable="false">
            <TestPaper ref="testPaper" :paper="evaluationInfo"></TestPaper>
        </Modal>
    </div>
</template>
<script>
import blobTool from '@/utils/blobTool.js'
import BaseImport from '@/view/evaluation/components/BaseImport.vue'
import TestPaper from '@/view/evaluation/index/TestPaper.vue'
export default {
    components: {
        BaseImport, TestPaper
    },
    data() {
        return {
            modalLoading: true,
            routerScope: '',
            importStatus: false,
            errorList: [],
            evaluationInfo: {
                name: '测试创建评测导入试卷',
                target: [],
                type: 'private',
                publish: '',
                paperPeriod: 0,
                paperGrade: [],
                paperSubject: 0,
                score: 100,
                item: [],
                startTime: 0,
                endTime: 0,
                createType: 'auto'
            },
        }
    },
    methods: {
        //导入试卷解析完成
        async onImportFinish(list) {
            this.errorList = []
            this.evaluationInfo.item = []
            let importList = await this.refreshImportItems(list)
            this.evaluationInfo.item = importList
            console.log(this.evaluationInfo)
            console.log('error', this.errorList)
            if (this.errorList.length) {
                this.$EventBus.$emit('importFinish', this.errorList)
            } else {
                this.importStatus = true
            }
        },
        /* 给导入的试题 补充最新的试卷学段年级以及科目信息 */
        refreshImportItems(list) {
            return new Promise((r, j) => {
                let objectiveTypes = ['single', 'multiple']
                let code = this.routerScope == 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId
                let gradeIds = []
                let subjectId = ''
                let periodId = ''
                for (let j = 0; j < list.length; j++) {
                    let i = list[j]
                    if (i.blob && i.id) {
                        console.log('题目已存在不需要刷新基础信息')
                        continue;
                    }
                    /* 如果是导入的试题 没有ID 则试题的信息和当前试卷的学段信息保持一致 */
                    i.id = this.$tools.guid()
                    i.code = code
                    i.level = 3
                    i.field = 1
                    i.scope = this.isSchool ? 'school' : 'private'
                    i.gradeIds = gradeIds
                    i.subjectId = ''
                    i.periodId = ''
                    if (i.children.length) {
                        i.children.forEach(j => {
                            j.id = this.$tools.guid()
                            j.pid = i.id
                            j.scope = i.scope
                            j.code = code
                            j.level = 3
                            j.field = 1
                            j.gradeIds = []
                            j.subjectId = []
                            j.periodId = []
                        })
                    }
                    // 如果导入的是客观题 则需要检测答案与选项是否为空
                    if (objectiveTypes.includes(i.type) && (!i.question.replace(/\s*/g, "") || !i.option.length || !i.answer.length)) {
                        this.errorList.push(i)
                    }
                }
                r(list)
            })
        },
        /** 保存当前试卷数据 */
        async saveTestPaper() {
            this.importStatus = true
            let exListVm = this.$refs.testPaper.$refs.exList
            let hasSurplus = exListVm.surPlusScore // 判断是否有剩余分数未分配
            let noScoreList = exListVm.exerciseList.filter(item => item.score === 0) // 判断是否有未配分的题目
            let hasErrorItem = exListVm.errorList.length > 0
            let groupTypeList = exListVm.groupTypeList
            let list = this.evaluationInfo.item
            this.$refs.testPaper.isShowAnalysis = false
            if (this.evaluationInfo.name.trim() === '') {
                this.$Message.warning('试卷名称不能为空！')
                return
            }
            if (!hasErrorItem) {
                if (hasSurplus === 0) {
                    if (!noScoreList.length) {
                        this.isLoading = true
                        let isPaperExist = await this.isPaperExist(this.evaluationInfo.name)
                        let isContainerFull = await this.isContainerFull()
                        if (!isPaperExist) {
                            if (list.length) {
                                // 拿到题型顺序的试题数组进行拼接
                                let arr = []
                                groupTypeList.forEach(i => {
                                    arr = arr.concat(i.list)
                                })
                                if (!this.checkComposeScore(arr)) return
                                if (isContainerFull) {
                                    this.$Message.warning('空间已满！')
                                } else {
                                    this.doSavePaper(arr)
                                }
                            } else {
                                this.$Message.warning('未选择任何试题！')
                            }
                        } else {
                            this.$Modal.confirm({
                                title: '温馨提示',
                                content: '<p>试卷库已存在重复名称试卷，是否继续保存覆盖原试卷？</p>',
                                okText: '确认',
                                cancelText: '取消',
                                onOk: async () => {
                                    // 拿到题型顺序的试题数组进行拼接
                                    let arr = []
                                    groupTypeList.forEach(i => {
                                        arr = arr.concat(i.list)
                                    })
                                    this.isLoading = true
                                    if (!this.checkComposeScore(arr)) return
                                    let blobList = await this.getPaperFiles('paper/' + this.evaluationInfo.name)
                                    let files = blobList.blobList.map(i => i.blob)
                                    this.onDeleteBlobPaper(files).then(r => {
                                        if (isContainerFull) {
                                            this.$Message.warning('空间已满！')
                                        } else {
                                            this.doSavePaper(arr)
                                        }
                                    })
                                },
                                onCancel: () => {
                                    this.isLoading = false
                                    this.$Message.warning('取消保存试卷')
                                }
                            })
                        }
                    } else {
                        this.$Message.warning(`存在未配分的题目，请配分后再保存！`)
                        this.isLoading = false
                    }
                } else {
                    this.$Message.warning({
                        content: `题目配分与试卷总分不一致！`,
                        duration: 2.5
                    })
                    this.isLoading = false
                    this.modalLoading = false
                    setTimeout(() => {
                        this.modalLoading = true
                    }, 100)
                }
            } else {
                this.$Message.warning(`存在异常试题，请修改或者重新导入！`)
                this.isLoading = false
            }
        },
        // 判断试卷是否存在于Blob中
        isPaperExist(paperName) {
            return new Promise(async (r, j) => {
                // 获取初始化Blob需要的数据
                let sasData = this.routerScope == 'school' ? await this.$tools.getSchoolSas() : await this.$tools.getPrivateSas()
                //初始化Blob
                let containerClient = new blobTool(sasData.url, sasData.name, sasData.sas, this.isSchool ? 'school' : 'private')
                containerClient.exists('paper/' + paperName + '/index.json').then(
                    (res) => {
                        r(res)
                    },
                    (err) => {
                        j(err)
                        this.$Message.error('API Error')
                    }
                )
            })
        },
        // 判断空间是否已满
        isContainerFull() {
            return new Promise(async (r, j) => {
                let scope = this.routerScope
                // 获取初始化Blob需要的数据
                let sasData = this.routerScope == 'school' ? await this.$tools.getSchoolSas() : await this.$tools.getPrivateSas()
                //初始化Blob
                let containerClient = new blobTool(sasData.url, sasData.name, sasData.sas, scope)
                containerClient.isContainerFull(scope).then(
                    (res) => {
                        r(res)
                    },
                    (err) => {
                        j(err)
                        this.$Message.error('API Error')
                    }
                )
            })
        },
        /* 检查综合题配分是否正确 */
        checkComposeScore(arr) {
            let flag = true
            arr.forEach((i, index) => {
                if (i.type === 'compose' && i.children.length) {
                    let childTotalScore = i.children.reduce((p, e) => parseInt(p) + parseInt(e.score), 0)
                    let hasNoScoreChild = i.children.filter(j => !j.score).length > 0
                    if (i.score !== childTotalScore || hasNoScoreChild) {
                        let exList = this.$refs.testPaper.$refs.exList
                        let exerciseDom = Array.from(exList.$el.getElementsByClassName('exercise-item')).filter(item => item.dataset.id ===
                            i.id)[0]
                        exerciseDom.style.backgroundColor = '#ffa7a7'
                        this.$nextTick(() => {
                            if (this.$refs.paperRef) {
                                this.$refs['paperRef'].scrollTo({
                                    y: exerciseDom.offsetTop
                                },
                                    500
                                )
                            }
                        })
                        setTimeout(() => {
                            exerciseDom.style.backgroundColor = '#fff'
                        }, 2000)
                        this.$Message.warning(`第 ${index + 1} 题综合题的配分${i.score > childTotalScore ? '不足' : '溢出'}，请检查后重试！`)
                        flag = false
                    }
                } else {
                    flag = true
                }
            })

            return flag
        },
        /* 保存试卷业务 */
        async doSavePaper(list) {
            console.log('保存的试卷题目集合', list)
            this.isLoading = true
            let multipleRule = this.$refs.testPaper.$refs.exList.multipleRule
            let modifyItems = this.$refs.testPaper.$refs.exList.modifyItems
            // 将传进来的试题 如果是导入的试题 则需要补充年级学段等信息
            let refreshList = await this.refreshImportItems(list)
            // 保存导入的试题到BLOB以及COSMOS
            this.savePaperItems(refreshList, modifyItems, this.isEditPaper).then(
                async res => {
                    console.log('savePaperItems成功')
                    let guid = this.$tools.guid()
                    let paperItem = {
                        id: this.evaluationInfo.id || guid,
                        code: this.editPaper ? this.editPaper.code : (this.isSchool ? this.$store.state.userInfo.schoolCode : this.$store
                            .state.userInfo.TEAMModelId),
                        scope: this.isSchool ? 'school' : 'private',
                        gradeIds: this.isSchool ? (this.evaluationInfo.paperGrade.length ? this.evaluationInfo.paperGrade : this.gradeList
                            .map(i => i.id)) : [],
                        subjectId: this.isSchool ? this.subjectList[this.evaluationInfo.paperSubject].id : null,
                        subjectName: this.isSchool ? this.subjectList[this.evaluationInfo.paperSubject].name : '',
                        periodId: this.isSchool ? this.schoolInfo.period[this.evaluationInfo.paperPeriod].id : null,
                        name: this.evaluationInfo.name,
                        points: this.getPaperPoints(this.evaluationInfo.item),
                        scoring: this.getAnswers(list),
                        score: this.evaluationInfo.score,
                        multipleRule: multipleRule || 1
                    }
                    let blobPaper = await this.$evTools.createBlobPaper(paperItem, res.slides)
                    // 首先保存新题目的JSON文件到Blob 然后返回URL链接
                    let paperFile = new File([JSON.stringify(blobPaper)], "index.json");
                    // 获取初始化Blob需要的数据
                    let sasData = this.evaluationInfo.type === 'private' ? await this.$tools.getPrivateSas() : await this.$tools.getSchoolSas()
                    //初始化Blob
                    let containerClient = new blobTool(sasData.url, sasData.name, sasData.sas, this.evaluationInfo.type)
                    try {
                        let promiseArr = []
                        let blobFile = null

                        console.log('试卷题目的ID集合', res.files)
                        console.log('试卷ITEM', paperItem)
                        // return
                        let privateSas = await this.$tools.getPrivateSas()
                        let privateBlob = new blobTool(privateSas.url, privateSas.name, privateSas.sas, 'private')
                        let schoolSas = await this.$tools.getSchoolSas()
                        let schoolBlob = new blobTool(schoolSas.url, schoolSas.name, schoolSas.sas, 'school')

                        // 放入试题json文件以及index.json文件
                        for (let i = 0; i < res.files.length; i++) {
                            promiseArr.push(new Promise(async (r, j) => {
                                // let result = await containerClient.upload(res.files[i], 'paper/' + paperItem.name, undefined, false)
                                // r(result)

                                let item = res.files[i]
                                if (item.scope == 'school') {
                                    containerClient.copyFolder('paper/' + paperItem.name + '/', 'item/' + item.id, schoolBlob)
                                } else {
                                    containerClient.copyFolder('paper/' + paperItem.name + '/', 'item/' + item.id, privateBlob)
                                }
                                r(200)
                            }))


                        }
                        promiseArr.push(new Promise(async (r, j) => {
                            try {
                                blobFile = await containerClient.upload(paperFile, 'paper/' + paperItem.name, undefined, false)
                                console.log('上传到试卷目录下', blobFile)
                                r(blobFile)
                            } catch (e) {
                                j(e)
                                this.$Message.error(e.spaceError)
                                this.isLoading = false
                            }

                        }))
                        // 进行试卷文件上传Blob
                        Promise.all(promiseArr).then(async result => {
                            console.log('试卷上传文件的promise结果', result)
                            if (blobFile.blob) {
                                // 保存到COSMOS是不含base64图片编码的数据 避免数据量过大
                                paperItem.blob = blobFile.blob.split('/index.json')[0]
                                let params = {
                                    paper: await this.$evTools.createCosmosPaper(paperItem),
                                    option: this.isEditPaper ? 'update' : 'insert'
                                }
                                //  保存试卷到cosmos
                                this.$api.learnActivity.SaveExamPaper(params).then(
                                    res => {
                                        if (res.error == null) {
                                            this.$Message.success(this.isEditPaper ? '编辑成功' : '保存成功')
                                            this.isLoading = false
                                            this.$router.push({
                                                name: this.evaluationInfo.type === 'private' ? 'personalBank' : 'schoolBank',
                                                params: {
                                                    tabName: 'paper'
                                                }
                                            })
                                        } else {
                                            this.$Message.error('保存试卷失败')
                                            this.isLoading = false
                                        }
                                    },
                                    err => {
                                        this.$Message.error('保存试卷失败')
                                        this.isLoading = false
                                    }
                                )
                            }
                        })
                    } catch (e) {
                        this.$Message.error('上传失败！')
                        console.log(e)
                        this.isLoading = false
                    }
                },
                err => {
                    console.log('savePaperItems失败')
                }).finally(() => {
                    console.log('savePaperItems结束')
                })
        },
        /* 将list中的试题 保存到Cosmos以及Blob中 */
        async savePaperItems(list, modifyItems, isEdit) {
            let that = this
            console.log('保存的试题列表')
            console.log(list)
            // 获取初始化Blob需要的数据
            let sasData = this.isSchool ? await this.$tools.getSchoolSas() : await this.$tools.getPrivateSas()
            let itemJsonFiles = []
            //初始化Blob
            let containerClient = new blobTool(sasData.url, sasData.name, sasData.sas, this.evaluationInfo.type)
            return new Promise(async (resolve, j) => {
                let promiseArr = []
                for (let i = 0; i < list.length; i++) {
                    let exerciseItem = list[i]
                    console.log(exerciseItem)
                    // 如果是编辑试卷状态 或者 从题目是来自题库
                    if (isEdit || exerciseItem.blob) {
                        if (exerciseItem.children.length) {
                            // 如果是编辑状态下的综合题
                            let composeArr = [exerciseItem, ...exerciseItem.children]
                            composeArr.forEach(composeItem => {
                                promiseArr.push(new Promise(async (r, j) => {
                                    if (composeItem.children.length && composeItem.children[0].id) {
                                        composeItem.children = composeItem.children.map(i => i.id)
                                    }
                                    // 保存试题的blob链接
                                    const itemJsonFile = await this.$evTools.createBlobItem(composeItem)
                                    let file = new File([JSON.stringify(itemJsonFile)], composeItem.id + ".json");
                                    itemJsonFiles.push(composeItem)
                                    r(composeItem)
                                    console.log(composeItem)
                                }))
                            })
                        } else {
                            // 如果已有blob字段 说明是已经保存到blob的试题 只需要将最新试题更新到paper目录下（自动手动挑题情况）
                            promiseArr.push(new Promise(async (r, j) => {
                                // 保存试题的blob链接
                                const itemJsonFile = await this.$evTools.createBlobItem(exerciseItem)
                                let file = new File([JSON.stringify(itemJsonFile)], exerciseItem.id + ".json");
                                itemJsonFiles.push(exerciseItem)
                                r(exerciseItem)
                            }))
                        }
                    } else if (exerciseItem.children.length) { //如果是导入的 综合题
                        // 如果是综合题 则需要把题干和小题都进行保存操作
                        let composeArr = [exerciseItem, ...exerciseItem.children]
                        composeArr.forEach(composeItem => {
                            promiseArr.push(new Promise(async (r, j) => {
                                if (composeItem.children.length && composeItem.children[0].id) {
                                    composeItem.children = composeItem.children.map(i => i.id)
                                }
                                // 将当前的试题数据转化为BLOB内部的试题JSON格式
                                const itemJsonFile = await this.$evTools.createBlobItem(composeItem)
                                const cosmosItem = await this.$evTools.createCosmosItem(composeItem)
                                // 首先保存新题目的JSON文件到Blob 然后返回URL链接
                                let file = new File([JSON.stringify(itemJsonFile)], composeItem.id + ".json");
                                try {
                                    // 等待上传blob的返回结果
                                    let blobFile = await containerClient.upload(file, 'item/' + composeItem.id, undefined, false)
                                    if (blobFile.blob) {
                                        // 保存试题JSON文件到试卷文件夹需要
                                        itemJsonFiles.push(composeItem)
                                        // 保存到COSMOS是不含base64图片编码的数据 避免数据量过大
                                        cosmosItem.blob = blobFile.blob
                                        // 保存当前试题到数据库
                                        that.saveExercise(cosmosItem).then(res => {
                                            r(composeItem)
                                        })
                                    } else {
                                        j(500)
                                    }
                                } catch (e) {
                                    console.log('------', e)
                                    this.$Message.error(e.spaceError)
                                    this.isLoading = false
                                }
                            }))
                        })
                    } else {
                        // 如果没有blob字段 说明试题还没有保存到item目录下 则需要进行保存item文件夹后再保存到paper文件夹（导入试题情况）
                        promiseArr.push(new Promise(async (r, j) => {
                            // 将当前的试题数据转化为BLOB内部的试题JSON格式
                            const itemJsonFile = await this.$evTools.createBlobItem(exerciseItem)
                            const cosmosItem = await this.$evTools.createCosmosItem(exerciseItem)
                            // 首先保存新题目的JSON文件到Blob 然后返回URL链接
                            let file = new File([JSON.stringify(itemJsonFile)], exerciseItem.id + ".json");
                            try {
                                // 等待上传blob的返回结果
                                let blobFile = await containerClient.upload(file, 'item/' + exerciseItem.id, undefined, false)
                                if (blobFile.blob) {
                                    // 保存试题JSON文件到试卷文件夹需要
                                    itemJsonFiles.push(exerciseItem)
                                    // 保存到COSMOS是不含base64图片编码的数据 避免数据量过大
                                    cosmosItem.blob = blobFile.blob
                                    // 保存当前试题到数据库
                                    that.saveExercise(cosmosItem).then(res => {
                                        r(exerciseItem)
                                    })
                                } else {
                                    j(500)
                                }
                            } catch (e) {
                                this.$Message.error(e.spaceError)
                                this.isLoading = false
                            }
                        }))
                    }
                }
                Promise.all(promiseArr).then(result => {
                    console.log(result)
                    let slides = []
                    // 主观题的answer为空数组
                    let nullType = ['complete', 'subjective', 'compose']
                    result.forEach(item => {
                        let o = {
                            url: item.id + '.json',
                            type: item.type,
                            scoring: {
                                score: item.score,
                                knowledge: item.points || [],
                                field: item.field || 1,
                                ans: nullType.includes(item.type) ? [] : item.answer
                            }
                        }
                        item.type === 'compose' && delete o.scoring
                        slides.push(o)
                    })
                    resolve({
                        slides: slides,
                        files: itemJsonFiles
                    })
                }).catch(err => {
                    console.log(err)
                    this.$Message.error('操作失败')
                })
            })
        },
        /* 保存单个试题 */
        saveExercise(item) {
            item.code = item.scope === 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId
            return new Promise((r, j) => {
                this.$api.newEvaluation.SaveSingleExercise({
                    itemInfo: item,
                    // option: this.isEditPaper ? 'update' : 'insert'
                    option: 'insert'
                }).then(res => {
                    if (!res.error) {
                        r(res)
                    } else {
                        j(res)
                        this.$Message.error('服务器繁忙！')
                    }

                })
            })
        },
    },
    computed: {

    },
    created() {
        //判断创建个人还是校本评测
        if (this.$route.name == 'createSchoolEva') {
            this.routerScope = 'school'
        } else {
            this.routerScope = 'private'
        }
    }
}
</script>
<style lang="less">
@import "./ImportCreate.less";
</style>
<style>
</style>
