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

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.util.JacksonUtil;
import com.qmth.teachcloud.common.util.ServletUtil;
import com.qmth.teachcloud.report.business.bean.result.*;
import com.qmth.teachcloud.report.business.entity.TAExamCourse;
import com.qmth.teachcloud.report.business.entity.TBDimension;
import com.qmth.teachcloud.report.business.entity.TBExamCourse;
import com.qmth.teachcloud.report.business.entity.TBPaper;
import com.qmth.teachcloud.report.business.enums.GradeScopeEnum;
import com.qmth.teachcloud.report.business.enums.PiecewiseScopeEnum;
import com.qmth.teachcloud.report.business.enums.PublishStatusEnum;
import com.qmth.teachcloud.report.business.service.*;
import com.qmth.teachcloud.report.business.utils.AnalyzeScopeUtil;
import com.qmth.teachcloud.report.business.utils.MathUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 教研公共服务
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2021/6/4
 */
@Service
public class ReportCommonServiceImpl implements ReportCommonService {
    private final static Logger log = LoggerFactory.getLogger(ReportCommonServiceImpl.class);

    @Resource
    TBPaperService tbPaperService;

    @Resource
    TAExamCourseCollegeInspectService taExamCourseCollegeInspectService;

    @Resource
    TAExamCourseRecordService taExamCourseRecordService;

    @Resource
    TBDimensionService tbDimensionService;

    @Resource
    TAExamCourseCollegeTeacherService taExamCourseCollegeTeacherService;

    @Resource
    TAExamCourseDifficultService taExamCourseDifficultService;

    @Resource
    TAExamCourseTeacherDifficultService taExamCourseTeacherDifficultService;

    @Resource
    TBPaperStructService tbPaperStructService;

    @Resource
    TAExamCourseService taExamCourseService;

    @Resource
    TBExamCourseService tbExamCourseService;

    /**
     * 学院学科报表查询科目信息
     *
     * @param examId
     * @param courseCode
     * @param collegeId
     * @return
     */
    @Override
    public CourseInfoResult findCourseInfo(Long examId, String courseCode, Long collegeId) {
        //查找试卷
        QueryWrapper<TBPaper> tbPaperQueryWrapper = new QueryWrapper<>();
        tbPaperQueryWrapper.lambda().eq(TBPaper::getExamId, examId)
                .eq(TBPaper::getCourseCode, courseCode);
        List<TBPaper> tbPaperList = tbPaperService.list(tbPaperQueryWrapper);

        //查找学院科目维度
        List<TAExamCourseCollegeInspectResult> taExamCourseCollegeInspectResultList = taExamCourseCollegeInspectService.findCourseDescriptiveStatisticsForCollege(examId, courseCode, collegeId);
        //查找学校科目维度
        List<TAExamCourseCollegeInspectResult> taExamCourseSchoolInspectResultList = taExamCourseCollegeInspectService.findCourseDescriptiveStatisticsForSchool(examId, courseCode);

        // 课程概况
        if (tbPaperList.size() < 1) {
            throw ExceptionResultEnum.NO_DATA.exception();
        }
        Set<String> paperTypeSet = tbPaperList.stream().map(e -> e.getPaperType()).collect(Collectors.toSet());
        String paperType = String.join(",", paperTypeSet); // 多种试卷类型的试卷类型合并','号隔开
        Gson gson = new Gson();
        TBPaperInfoResult TBPaperInfoResult = gson.fromJson(gson.toJson(tbPaperList.get(0)), TBPaperInfoResult.class);
        TBPaperInfoResult.setPaperType(paperType);
        TBPaperInfoResult.setCollegeCount(taExamCourseCollegeInspectResultList.size());

//        // 学院该科目的描述统计
//        List<TAExamCourseCollegeInspectResult> collegeDescriptiveStatisticsList = taExamCourseCollegeInspectResultList
//                .stream().filter(e -> collegeId.longValue() == e.getCollegeId().longValue()).collect(Collectors.toList());
//        if (collegeDescriptiveStatisticsList.size() != 1) {
//            throw ExceptionResultEnum.DATA_COUNT_EXCEPTION.exception();
//        }
        if (taExamCourseCollegeInspectResultList.size() != 1) {
            throw ExceptionResultEnum.DATA_COUNT_EXCEPTION.exception();
        }
        TAExamCourseCollegeInspectResult collegeDescriptiveStatistics = taExamCourseCollegeInspectResultList.get(0);

        // 全校该科目的描述统计
        if (taExamCourseSchoolInspectResultList.size() != 1) {
            throw ExceptionResultEnum.DATA_COUNT_EXCEPTION.exception();
        }
        TAExamCourseCollegeInspectResult schoolDescriptiveStatistics = taExamCourseSchoolInspectResultList.get(0);
        DescriptiveStatisticsResult descriptiveStatisticsResult = new DescriptiveStatisticsResult(collegeDescriptiveStatistics, schoolDescriptiveStatistics);
        return new CourseInfoResult(TBPaperInfoResult, descriptiveStatisticsResult);
    }

    /**
     * 学院学科报表科目描述
     *
     * @param examId
     * @param courseCode
     * @param collegeId
     * @return
     */
    @Override
    public CollegeAndSchoolGradeDistributionResult findCourseDistribution(Long examId, String courseCode, Long collegeId) {
        List<ExamRecordResult> examPaperTikForSchool = taExamCourseRecordService.findExamRecordByExamIdAndCourseCode(examId, courseCode);
        List<ExamRecordResult> examPaperTikForCollege = examPaperTikForSchool
                .stream().filter(e -> collegeId.longValue() == e.getCollegeId().longValue()).collect(Collectors.toList());

        double colTotalCount = examPaperTikForCollege.size(); // 学院总参考人数
        double schTotalCount = examPaperTikForSchool.size(); // 全校总参考人数
        if (schTotalCount < 1 || colTotalCount < 1) {
            throw ExceptionResultEnum.DATA_ERROR.exception();
        }

        // 计算成绩分布图
        List<GradeDistributionResult> gradeDistributionList = new ArrayList<>();
        for (GradeScopeEnum value : GradeScopeEnum.values()) {
            String describe = value.getDescribe();
            double colCount = 0;
            double schCount = 0;

            Map<String, Object> scopeMap = AnalyzeScopeUtil.analyzeScope(value.getScope());
            String minSign = String.valueOf(scopeMap.get("minSign"));
            String maxSign = String.valueOf(scopeMap.get("maxSign"));
            double minValue = Double.parseDouble(String.valueOf(scopeMap.get("minValue")));
            double maxValue = Double.parseDouble(String.valueOf(scopeMap.get("maxValue")));
            if ("(".equals(minSign) && ")".equals(maxSign)) {
                colCount = (int) examPaperTikForCollege.stream()
                        .filter(e -> minValue < e.getAssignedScore().doubleValue() && maxValue > e.getAssignedScore().doubleValue()).count();
                schCount = (int) examPaperTikForSchool.stream()
                        .filter(e -> minValue < e.getAssignedScore().doubleValue() && maxValue > e.getAssignedScore().doubleValue()).count();

            } else if ("(".equals(minSign) && "]".equals(maxSign)) {
                colCount = (int) examPaperTikForCollege.stream()
                        .filter(e -> minValue < e.getAssignedScore().doubleValue() && maxValue >= e.getAssignedScore().doubleValue()).count();
                schCount = (int) examPaperTikForSchool.stream()
                        .filter(e -> minValue < e.getAssignedScore().doubleValue() && maxValue >= e.getAssignedScore().doubleValue()).count();

            } else if ("[".equals(minSign) && ")".equals(maxSign)) {
                colCount = (int) examPaperTikForCollege.stream()
                        .filter(e -> minValue <= e.getAssignedScore().doubleValue() && maxValue > e.getAssignedScore().doubleValue()).count();
                schCount = (int) examPaperTikForSchool.stream()
                        .filter(e -> minValue <= e.getAssignedScore().doubleValue() && maxValue > e.getAssignedScore().doubleValue()).count();

            } else if ("[".equals(minSign) && "]".equals(maxSign)) {
                colCount = (int) examPaperTikForCollege.stream()
                        .filter(e -> minValue <= e.getAssignedScore().doubleValue() && maxValue >= e.getAssignedScore().doubleValue()).count();
                schCount = (int) examPaperTikForSchool.stream()
                        .filter(e -> minValue <= e.getAssignedScore().doubleValue() && maxValue >= e.getAssignedScore().doubleValue()).count();
            }

            gradeDistributionList.add(new GradeDistributionResult(colCount, schCount, describe));
        }

        // 计算分数段分布
        List<PiecewiseDistributionResult> piecewiseDistributionList = new ArrayList<>();
        for (PiecewiseScopeEnum value : PiecewiseScopeEnum.values()) {
            String remark = value.getRemark();
            String name = value.getName();
            double colCount = 0;
            double schCount = 0;

            Map<String, Object> scopeMap = AnalyzeScopeUtil.analyzeScope(value.getScope());
            String minSign = String.valueOf(scopeMap.get("minSign"));
            String maxSign = String.valueOf(scopeMap.get("maxSign"));
            double minValue = Double.parseDouble(String.valueOf(scopeMap.get("minValue")));
            double maxValue = Double.parseDouble(String.valueOf(scopeMap.get("maxValue")));
            if ("(".equals(minSign) && ")".equals(maxSign)) {
                colCount = (int) examPaperTikForCollege.stream()
                        .filter(e -> minValue < e.getPercentGrade().doubleValue() && maxValue > e.getPercentGrade().doubleValue()).count();
                schCount = (int) examPaperTikForSchool.stream()
                        .filter(e -> minValue < e.getPercentGrade().doubleValue() && maxValue > e.getPercentGrade().doubleValue()).count();

            } else if ("(".equals(minSign) && "]".equals(maxSign)) {
                colCount = (int) examPaperTikForCollege.stream()
                        .filter(e -> minValue < e.getPercentGrade().doubleValue() && maxValue >= e.getPercentGrade().doubleValue()).count();
                schCount = (int) examPaperTikForSchool.stream()
                        .filter(e -> minValue < e.getPercentGrade().doubleValue() && maxValue >= e.getPercentGrade().doubleValue()).count();

            } else if ("[".equals(minSign) && ")".equals(maxSign)) {
                colCount = (int) examPaperTikForCollege.stream()
                        .filter(e -> minValue <= e.getPercentGrade().doubleValue() && maxValue > e.getPercentGrade().doubleValue()).count();
                schCount = (int) examPaperTikForSchool.stream()
                        .filter(e -> minValue <= e.getPercentGrade().doubleValue() && maxValue > e.getPercentGrade().doubleValue()).count();

            } else if ("[".equals(minSign) && "]".equals(maxSign)) {
                colCount = (int) examPaperTikForCollege.stream()
                        .filter(e -> minValue <= e.getPercentGrade().doubleValue() && maxValue >= e.getPercentGrade().doubleValue()).count();
                schCount = (int) examPaperTikForSchool.stream()
                        .filter(e -> minValue <= e.getPercentGrade().doubleValue() && maxValue >= e.getPercentGrade().doubleValue()).count();
            }
            double colCountRate = MathUtil.formatDouble2(colCount / colTotalCount * 100); //本院比率 保留2位小数
            double schCountRate = MathUtil.formatDouble2(schCount / schTotalCount * 100); //全校比率 保留2位小数

            piecewiseDistributionList.add(new PiecewiseDistributionResult(name, colCount, colCountRate, schCount, schCountRate, remark));
        }
        return new CollegeAndSchoolGradeDistributionResult(gradeDistributionList, piecewiseDistributionList);
    }

    /**
     * 开课学院分数段
     *
     * @param examId
     * @param courseCode
     * @param collegeId
     * @param filter
     * @return
     */
    @Override
    public List<SurveyTeacherGradeDistributionResult> surveyTeacherDistribution(Long examId, String courseCode, Long collegeId, boolean filter) {
        List<SurveyTeacherGradeDistributionResult> surveyTeacherGradeDistributionResultList = new ArrayList<>();
        List<SurveyTeacherDistributionResult> surveyTeacherDistributionResultList = taExamCourseRecordService.surveyTeacherDistribution(examId, courseCode, filter);
        if (Objects.isNull(surveyTeacherDistributionResultList) && surveyTeacherDistributionResultList.size() > 0) {
            return null;
        }
        surveyTeacherDistributionResultList = surveyTeacherDistributionResultList.stream().filter(e -> !e.getAbsent()).collect(Collectors.toList());
        //过滤应届
        List<SurveyTeacherDistributionResult> currentDistributionResultList = surveyTeacherDistributionResultList.stream().filter(e -> e.getStudentCurrent() == true && !e.getAbsent()).collect(Collectors.toList());
        double allTotalCount = surveyTeacherDistributionResultList.size(); // 总体人数
        double currentTotalCount = currentDistributionResultList.size(); // 应届人数

        // 计算成绩分布图
        for (GradeScopeEnum value : GradeScopeEnum.values()) {
            String describe = value.getDescribe();
            double allCountBefore = 0, allCountAfter = 0, currentCountBefore = 0, currentCountAfter = 0,
                    allCountRateBefore = 0, allCountRateAfter = 0, currentCountRateBefore = 0, currentCountRateAfter = 0;

            Map<String, Object> scopeMap = AnalyzeScopeUtil.analyzeScope(value.getScope());
            String minSign = String.valueOf(scopeMap.get("minSign"));
            String maxSign = String.valueOf(scopeMap.get("maxSign"));
            double minValue = Double.parseDouble(String.valueOf(scopeMap.get("minValue")));
            double maxValue = Double.parseDouble(String.valueOf(scopeMap.get("maxValue")));
            if ("(".equals(minSign) && ")".equals(maxSign)) {
                allCountBefore = (int) surveyTeacherDistributionResultList.stream()//赋分前
                        .filter(e -> minValue < e.getTotalScore().doubleValue() && maxValue > e.getTotalScore().doubleValue()).count();
                allCountAfter = (int) surveyTeacherDistributionResultList.stream()
                        .filter(e -> minValue < e.getAssignedScore().doubleValue() && maxValue > e.getAssignedScore().doubleValue()).count();
                currentCountBefore = (int) currentDistributionResultList.stream()//赋分前
                        .filter(e -> minValue < e.getTotalScore().doubleValue() && maxValue > e.getTotalScore().doubleValue()).count();
                currentCountAfter = (int) currentDistributionResultList.stream()
                        .filter(e -> minValue < e.getAssignedScore().doubleValue() && maxValue > e.getAssignedScore().doubleValue()).count();
            } else if ("(".equals(minSign) && "]".equals(maxSign)) {
                allCountBefore = (int) surveyTeacherDistributionResultList.stream()//赋分前
                        .filter(e -> minValue < e.getTotalScore().doubleValue() && maxValue >= e.getTotalScore().doubleValue()).count();
                allCountAfter = (int) surveyTeacherDistributionResultList.stream()
                        .filter(e -> minValue < e.getAssignedScore().doubleValue() && maxValue >= e.getAssignedScore().doubleValue()).count();
                currentCountBefore = (int) currentDistributionResultList.stream()//赋分前
                        .filter(e -> minValue < e.getTotalScore().doubleValue() && maxValue >= e.getTotalScore().doubleValue()).count();
                currentCountAfter = (int) currentDistributionResultList.stream()
                        .filter(e -> minValue < e.getAssignedScore().doubleValue() && maxValue >= e.getAssignedScore().doubleValue()).count();
            } else if ("[".equals(minSign) && ")".equals(maxSign)) {
                if (maxValue == 100) {
                    allCountBefore = (int) surveyTeacherDistributionResultList.stream()//赋分前
                            .filter(e -> minValue <= e.getTotalScore().doubleValue() && maxValue >= e.getTotalScore().doubleValue()).count();
                    allCountAfter = (int) surveyTeacherDistributionResultList.stream()
                            .filter(e -> minValue <= e.getAssignedScore().doubleValue() && maxValue >= e.getAssignedScore().doubleValue()).count();
                    currentCountBefore = (int) currentDistributionResultList.stream()//赋分前
                            .filter(e -> minValue <= e.getTotalScore().doubleValue() && maxValue >= e.getTotalScore().doubleValue()).count();
                    currentCountAfter = (int) currentDistributionResultList.stream()
                            .filter(e -> minValue <= e.getAssignedScore().doubleValue() && maxValue >= e.getAssignedScore().doubleValue()).count();
                } else {
                    allCountBefore = (int) surveyTeacherDistributionResultList.stream()//赋分前
                            .filter(e -> minValue <= e.getTotalScore().doubleValue() && maxValue > e.getTotalScore().doubleValue()).count();
                    allCountAfter = (int) surveyTeacherDistributionResultList.stream()
                            .filter(e -> minValue <= e.getAssignedScore().doubleValue() && maxValue > e.getAssignedScore().doubleValue()).count();
                    currentCountBefore = (int) currentDistributionResultList.stream()//赋分前
                            .filter(e -> minValue <= e.getTotalScore().doubleValue() && maxValue > e.getTotalScore().doubleValue()).count();
                    currentCountAfter = (int) currentDistributionResultList.stream()
                            .filter(e -> minValue <= e.getAssignedScore().doubleValue() && maxValue > e.getAssignedScore().doubleValue()).count();
                }
            } else if ("[".equals(minSign) && "]".equals(maxSign)) {
                allCountBefore = (int) surveyTeacherDistributionResultList.stream()//赋分前
                        .filter(e -> minValue <= e.getTotalScore().doubleValue() && maxValue >= e.getTotalScore().doubleValue()).count();
                allCountAfter = (int) surveyTeacherDistributionResultList.stream()
                        .filter(e -> minValue <= e.getAssignedScore().doubleValue() && maxValue >= e.getAssignedScore().doubleValue()).count();
                currentCountBefore = (int) currentDistributionResultList.stream()//赋分前
                        .filter(e -> minValue <= e.getTotalScore().doubleValue() && maxValue >= e.getTotalScore().doubleValue()).count();
                currentCountAfter = (int) currentDistributionResultList.stream()
                        .filter(e -> minValue <= e.getAssignedScore().doubleValue() && maxValue >= e.getAssignedScore().doubleValue()).count();
            }
            BigDecimal hundredBig = new BigDecimal("100");
            allCountRateBefore = allTotalCount > 0 ? new BigDecimal(allCountBefore).multiply(hundredBig).divide(new BigDecimal(allTotalCount), SystemConstant.FINAL_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue() : 0;
            allCountRateAfter = allTotalCount > 0 ? new BigDecimal(allCountAfter).multiply(hundredBig).divide(new BigDecimal(allTotalCount), SystemConstant.FINAL_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue() : 0;
            currentCountRateBefore = currentTotalCount > 0 ? new BigDecimal(currentCountBefore).multiply(hundredBig).divide(new BigDecimal(currentTotalCount), SystemConstant.FINAL_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue() : 0;
            currentCountRateAfter = currentTotalCount > 0 ? new BigDecimal(currentCountAfter).multiply(hundredBig).divide(new BigDecimal(currentTotalCount), SystemConstant.FINAL_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue() : 0;

            surveyTeacherGradeDistributionResultList.add(new SurveyTeacherGradeDistributionResult((int) Math.abs(allCountBefore), (int) Math.abs(allCountAfter), (int) Math.abs(currentCountBefore), (int) Math.abs(currentCountAfter),
                    allCountRateBefore, allCountRateAfter, currentCountRateBefore, currentCountRateAfter, describe));
        }
        return surveyTeacherGradeDistributionResultList;
    }

    /**
     * 学院学科报表查询维度
     *
     * @param examId
     * @param courseCode
     * @param collegeId
     * @param teacherId
     * @return
     */
    @Override
    public DimensionAnalyzeResult findDimensionInfo(Long examId, String courseCode, Long collegeId, Long teacherId) {
        //查找维度
        List<CourseDimensionResult> dimensionInfoDatasource = null;
        if (Objects.isNull(teacherId) || Objects.equals(teacherId, "")) {
            dimensionInfoDatasource = tbDimensionService.findDimensionInfo(examId, courseCode, collegeId);
        } else {
            dimensionInfoDatasource = tbDimensionService.findDimensionByTeacherInfo(examId, courseCode, teacherId);
        }
//        if (dimensionInfoDatasource.size() < 1) {
//            throw ExceptionResultEnum.DATA_ERROR.exception();
//        }
        List<ModuleDimensionResult> dimensionAnalyzeList = new ArrayList<>();
        Set<String> moduleSet = dimensionInfoDatasource.stream().map(e -> e.getModule()).collect(Collectors.toSet()); // 考查模块集合
        for (String module : moduleSet) {
            List<CourseDimensionResult> dimensionInfoList = dimensionInfoDatasource
                    .stream().filter(e -> module.equals(e.getModule())).collect(Collectors.toList());

            List<DimensionInfoResult> dioList = new ArrayList<>();
            List<DimensionInfoResult> batterThanAll = new ArrayList<>(); // 掌握较好
            List<DimensionInfoResult> worseThanAll = new ArrayList<>(); // 掌握较差
            for (CourseDimensionResult courseDimensionResult : dimensionInfoList) {
                String dimensionCode = String.valueOf(courseDimensionResult.getDimensionCode());
                String dimensionName = String.valueOf(courseDimensionResult.getDimensionName());
                double schScoreRate = courseDimensionResult.getSchScoreRate();
                double colScoreRate = courseDimensionResult.getColScoreRate();
                if (colScoreRate >= schScoreRate) {
                    batterThanAll.add(new DimensionInfoResult(dimensionCode, dimensionName));
                } else {
                    worseThanAll.add(new DimensionInfoResult(dimensionCode, dimensionName));
                }
                dioList.add(new DimensionInfoResult(dimensionCode, dimensionName, String.valueOf(courseDimensionResult.getTotalCount()), String.valueOf(schScoreRate), String.valueOf(colScoreRate), courseDimensionResult.getDegree()));
            }
            dimensionAnalyzeList.add(new ModuleDimensionResult(module, dioList, batterThanAll, worseThanAll));
        }
        return new DimensionAnalyzeResult(dimensionAnalyzeList);
    }

    /**
     * 查找题目相关
     *
     * @param examId
     * @param courseCode
     * @param collegeId
     * @param teacherId
     * @return
     */
    @Override
    public QuestionInfoResult findSituationOfQuestions(Long examId, String courseCode, Long collegeId, Long teacherId) {
        //查找答题记录
        List<CellResult> answerDetailDatasource = null;
        if (Objects.isNull(teacherId) || Objects.equals(teacherId, "")) {
            answerDetailDatasource = taExamCourseDifficultService.findValidAnswerDetail(examId, courseCode, collegeId);
        } else {
            answerDetailDatasource = taExamCourseTeacherDifficultService.findValidAnswerDetail(examId, courseCode, teacherId);
        }
        Set<String> paperTypeList = answerDetailDatasource.stream().map(e -> e.getPaperType()).collect(Collectors.toSet());
        List<PaperTypeResult> questionInfoList = new ArrayList<>();
        for (String paperType : paperTypeList) {
            questionInfoList.add(new PaperTypeResult(paperType, answerDetailDatasource.stream().filter(e -> Objects.equals(paperType, e.getPaperType())).collect(Collectors.toList())));
        }
        return new QuestionInfoResult(questionInfoList);
    }

    /**
     * 查找老师信息
     *
     * @param examId
     * @param courseCode
     * @param collegeId
     * @return
     */
    @Override
    public TeacherInfoListResult findTeacherInfo(Long examId, String courseCode, Long collegeId) {
        //查找老师得分
        List<TAExamCourseTeacherResult> taExamCourseTeacherResultList = taExamCourseCollegeTeacherService.findTeacherInfo(examId, courseCode, collegeId);
        if (taExamCourseTeacherResultList.size() < 1) {
            throw ExceptionResultEnum.DATA_ERROR.exception();
        }
        return new TeacherInfoListResult(taExamCourseTeacherResultList);
    }

    /**
     * 查找题目信息
     *
     * @param examId
     * @param courseCode
     * @param collegeId
     * @return
     */
    @Override
    public QuestionListResult findQuestionInfo(Long examId, String courseCode, Long collegeId) {
        //查找试卷结构
        List<TBPaperStructResult> questionDatasource = tbPaperStructService.findQuestionInfo(examId, courseCode);
        //查找维度
        QueryWrapper<TBDimension> tbDimensionQueryWrapper = new QueryWrapper<>();
        tbDimensionQueryWrapper.lambda().eq(TBDimension::getExamId, examId)
                .eq(TBDimension::getCourseCode, courseCode);
        List<TBDimension> dimensionDataSource = tbDimensionService.list(tbDimensionQueryWrapper);

        Set<String> paperTypeSet = questionDatasource.stream().map(e -> e.getPaperType()).collect(Collectors.toSet());
        List<QuestionResult> questionList = new ArrayList<>();
        for (String paperType : paperTypeSet) {
            List<TBPaperStructResult> cellList = questionDatasource.stream()
                    .filter(e -> paperType.equals(e.getPaperType())).collect(Collectors.toList());

            for (TBPaperStructResult cell : cellList) {
                cell.setPaperType(null);
            }

            Set<String> knowledgeDimensionSet = new HashSet<>(), abilityDimensionSet = new HashSet<>();
            for (TBPaperStructResult cell : cellList) {
                String knowledgeDimension = cell.getKnowledgeDimension();
                String[] arr = knowledgeDimension.split(",");
                knowledgeDimensionSet.addAll(Arrays.asList(arr));

                if (Objects.nonNull(cell.getAbilityDimension())) {
                    String abilityDimension = cell.getAbilityDimension();
                    String[] arrAbilityDimension = abilityDimension.split(",");
                    abilityDimensionSet.addAll(Arrays.asList(arrAbilityDimension));
                }
            }
            List<String> knowledgeDimensionSort = MathUtil.sortDimension(new ArrayList<>(knowledgeDimensionSet)); // 经过特殊排序的知识点集合
            List<String> abilityDimensionSort = MathUtil.sortDimension(new ArrayList<>(abilityDimensionSet)); // 经过特殊排序的知识点集合

            List<DimensionInfoResult> dimensionList = new ArrayList<>();
            for (String dimensionCode : knowledgeDimensionSort) {
                String dimensionName = "";
                List<String> nameTwoList = dimensionDataSource.stream()
                        .filter(e -> dimensionCode.equals(e.getCodeSecond()))
                        .map(e -> e.getNameSecond()).collect(Collectors.toList());
                if (nameTwoList.size() < 1) {
                    List<String> tmpList = dimensionDataSource.stream()
                            .filter(e -> dimensionCode.equals(e.getCodePrimary()))
                            .map(e -> e.getNamePrimary()).collect(Collectors.toList());
                    if (tmpList.size() == 0) {
                        continue;
                    }
                    dimensionName = tmpList.get(0);
                } else {
                    dimensionName = nameTwoList.get(0);
                }
                dimensionList.add(new DimensionInfoResult(dimensionCode, dimensionName));
            }

            List<DimensionInfoResult> abilityDimensionList = new ArrayList<>();
            for (String dimensionCode : abilityDimensionSort) {
                String dimensionName = "";
                List<String> nameTwoList = dimensionDataSource.stream()
                        .filter(e -> dimensionCode.equals(e.getCodeSecond()))
                        .map(e -> e.getNameSecond()).collect(Collectors.toList());
                if (nameTwoList.size() < 1) {
                    List<String> tmpList = dimensionDataSource.stream()
                            .filter(e -> dimensionCode.equals(e.getCodePrimary()))
                            .map(e -> e.getNamePrimary()).collect(Collectors.toList());
                    if (tmpList.size() == 0) {
                        continue;
                    }
                    dimensionName = tmpList.get(0);
                } else {
                    dimensionName = nameTwoList.get(0);
                }
                abilityDimensionList.add(new DimensionInfoResult(dimensionCode, dimensionName));
            }
            questionList.add(new QuestionResult(paperType, cellList, dimensionList, abilityDimensionList));
        }
        return new QuestionListResult(questionList);
    }

    /**
     * 取总体平均分
     *
     * @param schoolId
     * @param courseCode
     * @param examId
     * @param filter
     * @return
     */
    @Override
    public SurveyTeacherExamCourseResult findAvgScore(Long schoolId, String courseCode, Long examId, boolean filter) {
        //取总体和应届平均分
        QueryWrapper<TAExamCourse> taExamCourseQueryWrapper = new QueryWrapper<>();
        if (Objects.nonNull(schoolId)) {
            taExamCourseQueryWrapper.lambda().eq(TAExamCourse::getSchoolId, schoolId);
        }
        if (Objects.nonNull(examId)) {
            taExamCourseQueryWrapper.lambda().eq(TAExamCourse::getExamId, examId);
        }
        if (Objects.nonNull(courseCode)) {
            taExamCourseQueryWrapper.lambda().eq(TAExamCourse::getCourseCode, courseCode);
        }
        if (filter) {
            QueryWrapper<TBExamCourse> tbExamCourseQueryWrapper = new QueryWrapper<>();
            if (Objects.nonNull(schoolId)) {
                tbExamCourseQueryWrapper.lambda().eq(TBExamCourse::getSchoolId, schoolId);
            }
            if (Objects.nonNull(examId)) {
                tbExamCourseQueryWrapper.lambda().eq(TBExamCourse::getExamId, examId);
            }
            if (Objects.nonNull(courseCode)) {
                tbExamCourseQueryWrapper.lambda().eq(TBExamCourse::getCourseCode, courseCode);
            }
            tbExamCourseQueryWrapper.lambda().eq(TBExamCourse::getPublishStatus, PublishStatusEnum.PUBLISH);
            TBExamCourse tbExamCourse = tbExamCourseService.getOne(tbExamCourseQueryWrapper);
            if (Objects.isNull(tbExamCourse)) {
                BigDecimal bigDecimal = new BigDecimal(0);
                return new SurveyTeacherExamCourseResult(bigDecimal, bigDecimal, bigDecimal, bigDecimal);
            }
        }
        TAExamCourse taExamCourse = taExamCourseService.getOne(taExamCourseQueryWrapper);
        BigDecimal bigDecimal = new BigDecimal(1);
        return new SurveyTeacherExamCourseResult(taExamCourse.getAvgScore(), bigDecimal.subtract(taExamCourse.getPassRate()).multiply(new BigDecimal("100")), taExamCourse.getCurrentAvgScore(), bigDecimal.subtract(taExamCourse.getCurrentPassRate()).multiply(new BigDecimal("100")));
    }

    /**
     * 武汉大学退出
     */
    @Override
    public void whuLogout() throws IOException {
        HttpServletRequest request = ServletUtil.getRequest();
        HttpServletResponse response = ServletUtil.getResponse();
        HttpSession session = request.getSession();
        if (Objects.nonNull(session)) {
            session.invalidate();
            log.info("logout is come in,session:{}", JacksonUtil.parseJson(session));
        }
        String casLogoutURL = "http://cas.whu.edu.cn/authserver/logout";
        // service后面带的参数为应用的访问地址，需要使用URLEncoder进行编码
        String redirectURL = casLogoutURL + "?service=" + URLEncoder.encode("http://cas.whu.edu.cn/authserver/login", SystemConstant.CHARSET_NAME);
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.sendRedirect(redirectURL);
    }
}
