package com.qmth.teachcloud.report.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qmth.teachcloud.common.bean.params.TBExamCourseDeleteParams;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.util.RedisUtil;
import com.qmth.teachcloud.report.business.entity.*;
import com.qmth.teachcloud.report.business.service.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description: 分析课程物理删除服务实现类
 * @Author: CaoZixuan
 * @Date: 2022-07-05
 */
@Service
public class TBExamCourseDeleteServiceImpl implements TBExamCourseDeleteService {
    // 无关联的基础表
    @Resource
    TBCommonLevelConfigService tbCommonLevelConfigService;
    @Resource
    TBCommonRankLevelConfigService tbCommonRankLevelConfigService;
    @Resource
    TBDimensionService tbDimensionService;
    @Resource
    TBExamCourseService tbExamCourseService;
    @Resource
    TBExamStudentService tbExamStudentService;
    @Resource
    TBModuleConfigService tbModuleConfigService;
    @Resource
    TBModuleProficiencyService tbModuleProficiencyService;

    // 相关联的基础表
    @Resource
    TBPaperService tbPaperService;
    @Resource
    TBPaperStructService tbPaperStructService;
    @Resource
    TBExamRecordService tbExamRecordService;
    @Resource
    TBAnswerService tbAnswerService;

    // 相关联的分析表
    @Resource
    TAExamCourseRecordService taExamCourseRecordService;
    @Resource
    TAExamCourseService taExamCourseService;
    @Resource
    TAExamCourseClazzService taExamCourseClazzService;
    @Resource
    TAExamCourseCollegeInspectService taExamCourseCollegeInspectService;
    @Resource
    TAExamCourseCollegeInspectDioService taExamCourseCollegeInspectDioService;
    @Resource
    TAExamCourseCollegePaperStructService taExamCourseCollegePaperStructService;
    @Resource
    TAExamCourseCollegeTeacherService taExamCourseCollegeTeacherService;
    @Resource
    TAExamCourseDifficultService taExamCourseDifficultService;
    @Resource
    TAExamCourseDioService taExamCourseDioService;
    @Resource
    TAExamCourseRecordDioService taExamCourseRecordDioService;
    @Resource
    TAExamCourseRecordModService taExamCourseRecordModService;
    @Resource
    TAExamCourseTeacherService taExamCourseTeacherService;
    @Resource
    TAExamCourseTeacherCollegeDifficultService taExamCourseTeacherCollegeDifficultService;
    @Resource
    TAExamCourseTeacherCollegeDioService taExamCourseTeacherCollegeDioService;
    @Resource
    TAExamCourseTeacherCollegePaperStructService taExamCourseTeacherCollegePaperStructService;
    @Resource
    TAExamCourseTeacherDifficultService taExamCourseTeacherDifficultService;
    @Resource
    TAExamCourseTeacherDioService taExamCourseTeacherDioService;
    @Resource
    TAExamCourseTeacherPaperStructService taExamCourseTeacherPaperStructService;
    @Resource
    TAPaperStructService taPaperStructService;

    // 重算
    @Resource
    AnalyzeForReportService analyzeForReportService;

    @Resource
    RedisUtil redisUtil;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteBasicTableData(Long schoolId, Long examId, String courseCode) {
        // 基础且无关联表删除
        tbCommonLevelConfigService.remove(new QueryWrapper<TBCommonLevelConfig>()
                .lambda()
                .eq(TBCommonLevelConfig::getExamId, examId)
                .eq(TBCommonLevelConfig::getCourseCode, courseCode));
        tbCommonRankLevelConfigService.remove(new QueryWrapper<TBCommonRankLevelConfig>()
                .lambda()
                .eq(TBCommonRankLevelConfig::getExamId, examId)
                .eq(TBCommonRankLevelConfig::getCourseCode, courseCode));
        tbDimensionService.remove(new QueryWrapper<TBDimension>()
                .lambda()
                .eq(TBDimension::getExamId, examId)
                .eq(TBDimension::getCourseCode, courseCode));
        tbExamCourseService.remove(new QueryWrapper<TBExamCourse>()
                .lambda()
                .eq(TBExamCourse::getSchoolId, schoolId)
                .eq(TBExamCourse::getExamId, examId)
                .eq(TBExamCourse::getCourseCode, courseCode));
        tbExamStudentService.remove(new QueryWrapper<TBExamStudent>()
                .lambda()
                .eq(TBExamStudent::getSchoolId, schoolId)
                .eq(TBExamStudent::getExamId, examId)
                .eq(TBExamStudent::getCourseCode, courseCode));
        tbModuleConfigService.remove(new QueryWrapper<TBModuleConfig>()
                .lambda()
                .eq(TBModuleConfig::getExamId, examId)
                .eq(TBModuleConfig::getCourseCode, courseCode));
        tbModuleProficiencyService.remove(new QueryWrapper<TBModuleProficiency>()
                .lambda()
                .eq(TBModuleProficiency::getExamId, examId)
                .eq(TBModuleProficiency::getCourseCode, courseCode));

        // 基础且关联表删除
        List<TBPaper> tbPaperList = tbPaperService.list(new QueryWrapper<TBPaper>()
                .lambda()
                .eq(TBPaper::getExamId, examId)
                .eq(TBPaper::getCourseCode, courseCode));
        if (tbPaperList != null && tbPaperList.size() > 0) {
            if (tbPaperList.size() > 1) {
                throw ExceptionResultEnum.ERROR.exception("考试id为【" + examId + "】，分析课程编号为【" + courseCode + "】存在多个试卷t_b_paper");
            }
            TBPaper tbPaper = tbPaperList.get(0);
            Long paperId = tbPaper.getId();
            List<TBPaperStruct> tbPaperStructList = tbPaperStructService.list(new QueryWrapper<TBPaperStruct>()
                    .lambda()
                    .eq(TBPaperStruct::getPaperId, paperId));
            List<TBExamRecord> tbExamRecordList = tbExamRecordService.list(new QueryWrapper<TBExamRecord>()
                    .lambda()
                    .eq(TBExamRecord::getExamId, examId)
                    .eq(TBExamRecord::getPaperId, paperId));
            List<Long> tbExamRecordIdList = tbExamRecordList.stream().map(TBExamRecord::getId).collect(Collectors.toList());
            if (tbExamRecordIdList.size() > 0) {
                List<TBAnswer> tbAnswerList = tbAnswerService.list(new QueryWrapper<TBAnswer>()
                        .lambda()
                        .in(TBAnswer::getExamRecordId, tbExamRecordIdList));
                // 删除't_b_answer'表
                tbAnswerService.removeByIds(tbAnswerList.stream().map(TBAnswer::getId).collect(Collectors.toList()));
            }
            // 删除't_b_exam_record'表
            tbExamRecordService.removeByIds(tbExamRecordIdList);
            // 删除't_b_paper_struct'表
            tbPaperStructService.removeByIds(tbPaperStructList.stream().map(TBPaperStruct::getId).collect(Collectors.toList()));
            // 删除't_b_paper'表
            tbPaperService.removeById(tbPaper.getId());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteAnalyzeTableData(Long schoolId, Long examId, String courseCode) {
        // 关联的分析表↓
        // 删除't_a_exam_course_record'
        List<TBPaper> tbPaperList = tbPaperService.list(new QueryWrapper<TBPaper>()
                .lambda()
                .eq(TBPaper::getExamId, examId)
                .eq(TBPaper::getCourseCode, courseCode));
        if (tbPaperList != null && tbPaperList.size() > 0) {
            if (tbPaperList.size() > 1) {
                throw ExceptionResultEnum.ERROR.exception("考试id为【" + examId + "】，分析课程编号为【" + courseCode + "】存在多个试卷t_b_paper");
            }
            TBPaper tbPaper = tbPaperList.get(0);
            Long paperId = tbPaper.getId();
            List<TBExamRecord> tbExamRecordList = tbExamRecordService.list(new QueryWrapper<TBExamRecord>()
                    .lambda()
                    .eq(TBExamRecord::getExamId, examId)
                    .eq(TBExamRecord::getPaperId, paperId));
            List<Long> tbExamRecordIdList = tbExamRecordList.stream().map(TBExamRecord::getId).collect(Collectors.toList());
            if (tbExamRecordIdList.size() > 0) {
                taExamCourseRecordService.remove(new QueryWrapper<TAExamCourseRecord>()
                        .lambda()
                        .in(TAExamCourseRecord::getExamRecordId, tbExamRecordIdList));
            }
        }
        // 独立的分析表↓
        // 删除't_a_exam_course'
        taExamCourseService.remove(new QueryWrapper<TAExamCourse>().lambda()
                .eq(TAExamCourse::getSchoolId, schoolId)
                .eq(TAExamCourse::getExamId, examId)
                .eq(TAExamCourse::getCourseCode, courseCode));
        // 删除't_a_exam_course_clazz'
        taExamCourseClazzService.remove(new QueryWrapper<TAExamCourseClazz>()
                .lambda()
                .eq(TAExamCourseClazz::getSchoolId, schoolId)
                .eq(TAExamCourseClazz::getExamId, examId)
                .eq(TAExamCourseClazz::getCourseCode, courseCode));
        // 删除't_a_exam_course_college_inspect'
        taExamCourseCollegeInspectService.remove(new QueryWrapper<TAExamCourseCollegeInspect>()
                .lambda()
                .eq(TAExamCourseCollegeInspect::getSchoolId, schoolId)
                .eq(TAExamCourseCollegeInspect::getExamId, examId)
                .eq(TAExamCourseCollegeInspect::getCourseCode, courseCode));
        // 删除't_a_exam_course_college_inspect_dio'
        taExamCourseCollegeInspectDioService.remove(new QueryWrapper<TAExamCourseCollegeInspectDio>()
                .lambda()
                .eq(TAExamCourseCollegeInspectDio::getSchoolId, schoolId)
                .eq(TAExamCourseCollegeInspectDio::getExamId, examId)
                .eq(TAExamCourseCollegeInspectDio::getCourseCode, courseCode));
        // 删除't_a_exam_course_college_paper_struct'
        taExamCourseCollegePaperStructService.remove(new QueryWrapper<TAExamCourseCollegePaperStruct>()
                .lambda()
                .eq(TAExamCourseCollegePaperStruct::getSchoolId, schoolId)
                .eq(TAExamCourseCollegePaperStruct::getExamId, examId)
                .eq(TAExamCourseCollegePaperStruct::getCourseCode, courseCode));
        // 删除't_a_exam_course_college_teacher'
        taExamCourseCollegeTeacherService.remove(new QueryWrapper<TAExamCourseCollegeTeacher>()
                .lambda()
                .eq(TAExamCourseCollegeTeacher::getSchoolId, schoolId)
                .eq(TAExamCourseCollegeTeacher::getExamId, examId)
                .eq(TAExamCourseCollegeTeacher::getCourseCode, courseCode));
        // 删除't_a_exam_course_difficult'
        taExamCourseDifficultService.remove(new QueryWrapper<TAExamCourseDifficult>()
                .lambda()
                .eq(TAExamCourseDifficult::getSchoolId, schoolId)
                .eq(TAExamCourseDifficult::getExamId, examId)
                .eq(TAExamCourseDifficult::getCourseCode, courseCode));
        // 删除't_a_exam_course_dio'
        taExamCourseDioService.remove(new QueryWrapper<TAExamCourseDio>().lambda()
                .eq(TAExamCourseDio::getSchoolId, schoolId)
                .eq(TAExamCourseDio::getExamId, examId)
                .eq(TAExamCourseDio::getCourseCode, courseCode));
        // 删除't_a_exam_course_record_dio'
        taExamCourseRecordDioService.remove(new QueryWrapper<TAExamCourseRecordDio>().lambda()
                .eq(TAExamCourseRecordDio::getSchoolId, schoolId)
                .eq(TAExamCourseRecordDio::getExamId, examId)
                .eq(TAExamCourseRecordDio::getCourseCode, courseCode));
        // 删除't_a_exam_course_record_mod'
        taExamCourseRecordModService.remove(new QueryWrapper<TAExamCourseRecordMod>().lambda()
                .eq(TAExamCourseRecordMod::getSchoolId, schoolId)
                .eq(TAExamCourseRecordMod::getExamId, examId)
                .eq(TAExamCourseRecordMod::getCourseCode, courseCode));
        // 删除't_a_exam_course_teacher'
        taExamCourseTeacherService.remove(new QueryWrapper<TAExamCourseTeacher>().lambda()
                .eq(TAExamCourseTeacher::getSchoolId, schoolId)
                .eq(TAExamCourseTeacher::getExamId, examId)
                .eq(TAExamCourseTeacher::getCourseCode, courseCode));
        // 删除't_a_exam_course_teacher_college_difficult'
        taExamCourseTeacherCollegeDifficultService.remove(new QueryWrapper<TAExamCourseTeacherCollegeDifficult>().lambda()
                .eq(TAExamCourseTeacherCollegeDifficult::getSchoolId, schoolId)
                .eq(TAExamCourseTeacherCollegeDifficult::getExamId, examId)
                .eq(TAExamCourseTeacherCollegeDifficult::getCourseCode, courseCode));
        // 删除't_a_exam_course_teacher_college_dio'
        taExamCourseTeacherCollegeDioService.remove(new QueryWrapper<TAExamCourseTeacherCollegeDio>().lambda()
                .eq(TAExamCourseTeacherCollegeDio::getSchoolId, schoolId)
                .eq(TAExamCourseTeacherCollegeDio::getExamId, examId)
                .eq(TAExamCourseTeacherCollegeDio::getCourseCode, courseCode));
        // 删除't_a_exam_course_teacher_college_paper_struct'
        taExamCourseTeacherCollegePaperStructService.remove(new QueryWrapper<TAExamCourseTeacherCollegePaperStruct>().lambda()
                .eq(TAExamCourseTeacherCollegePaperStruct::getSchoolId, schoolId)
                .eq(TAExamCourseTeacherCollegePaperStruct::getExamId, examId)
                .eq(TAExamCourseTeacherCollegePaperStruct::getCourseCode, courseCode));
        // 删除't_a_exam_course_teacher_difficult'
        taExamCourseTeacherDifficultService.remove(new QueryWrapper<TAExamCourseTeacherDifficult>().lambda()
                .eq(TAExamCourseTeacherDifficult::getSchoolId, schoolId)
                .eq(TAExamCourseTeacherDifficult::getExamId, examId)
                .eq(TAExamCourseTeacherDifficult::getCourseCode, courseCode));
        // 删除't_a_exam_course_teacher_dio'
        taExamCourseTeacherDioService.remove(new QueryWrapper<TAExamCourseTeacherDio>().lambda()
                .eq(TAExamCourseTeacherDio::getSchoolId, schoolId)
                .eq(TAExamCourseTeacherDio::getExamId, examId)
                .eq(TAExamCourseTeacherDio::getCourseCode, courseCode));
        // 删除't_a_exam_course_teacher_paper_struct'
        taExamCourseTeacherPaperStructService.remove(new QueryWrapper<TAExamCourseTeacherPaperStruct>().lambda()
                .eq(TAExamCourseTeacherPaperStruct::getSchoolId, schoolId)
                .eq(TAExamCourseTeacherPaperStruct::getExamId, examId)
                .eq(TAExamCourseTeacherPaperStruct::getCourseCode, courseCode));
        // 删除't_a_paper_struct'
        taPaperStructService.remove(new QueryWrapper<TAPaperStruct>().lambda()
                .eq(TAPaperStruct::getSchoolId, schoolId)
                .eq(TAPaperStruct::getExamId, examId)
                .eq(TAPaperStruct::getCourseCode, courseCode));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void repeatCalculateTotalTableData(Long schoolId, Long examId, String courseCode) {
        analyzeForReportService.buildAnalyzeExamTotal(examId, courseCode);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteTBExamCourse(List<TBExamCourseDeleteParams> tbExamCourseDeleteParamsList) {
        List<Long> schoolIdList = tbExamCourseDeleteParamsList.stream().map(TBExamCourseDeleteParams::getSchoolId).distinct().collect(Collectors.toList());
        if (schoolIdList.size() != 1){
            throw ExceptionResultEnum.ERROR.exception("学校信息异常");
        }
        Long lockSchoolId = schoolIdList.get(0);

        List<Long> examIdList = tbExamCourseDeleteParamsList.stream().map(TBExamCourseDeleteParams::getExamId).distinct().collect(Collectors.toList());
        if (examIdList.size() != 1){
            throw ExceptionResultEnum.ERROR.exception("不能删除不同考试下的分析课程");
        }
        Long lockExamId = examIdList.get(0);
        List<String> courseCodeList = tbExamCourseDeleteParamsList.stream().map(TBExamCourseDeleteParams::getCourseCode).distinct().sorted().collect(Collectors.toList());
        String lockCourseCode = DigestUtils.md5Hex(JSON.toJSONString(courseCodeList));
        String lockKey = SystemConstant.REDIS_LOCK_GRADE_COURSE_DELETE_PREFIX + lockSchoolId + SystemConstant.HYPHEN + lockExamId + SystemConstant.HYPHEN + lockCourseCode;

        boolean lock = redisUtil.lock(lockKey, SystemConstant.REDIS_LOCK_BATCH_NO_TIME_OUT);
        if (!lock) {
            throw ExceptionResultEnum.ERROR.exception("正在删除数据，请稍候再试!");
        }
        try {
            for (TBExamCourseDeleteParams tbExamCourseDeleteParams : tbExamCourseDeleteParamsList) {
                Long schoolId = tbExamCourseDeleteParams.getSchoolId();
                Long examId = tbExamCourseDeleteParams.getExamId();
                String courseCode = tbExamCourseDeleteParams.getCourseCode();
                if (tbExamCourseService.list(new QueryWrapper<TBExamCourse>()
                        .lambda()
                        .eq(TBExamCourse::getSchoolId,schoolId)
                        .eq(TBExamCourse::getExamId,examId)
                        .eq(TBExamCourse::getCourseCode,courseCode)).size() > 0){
                    // 教研分析有这个课程再删除，没有不删直接返回
                    if (tbExamCourseService.verifyExamCourseCantDelete(schoolId, examId, courseCode)) {
                        throw ExceptionResultEnum.ERROR.exception("考试id为【" + examId + "】，课程编号为【" + courseCode + "】的分析课程当前不能被删除");
                    }
                    // 先删分析表
                    this.deleteAnalyzeTableData(schoolId, examId, courseCode);
                    this.deleteBasicTableData(schoolId, examId, courseCode);
                    this.repeatCalculateTotalTableData(schoolId, examId, courseCode);
                }
            }
        } finally {
            redisUtil.releaseLock(lockKey);
        }

    }
}
