package com.xhkjedu.sexam.service.report;

import com.alibaba.fastjson.JSON;
import com.xhkjedu.sexam.mapper.exam.EClassMapper;
import com.xhkjedu.sexam.mapper.paper.EPaperAnalyzeMapper;
import com.xhkjedu.sexam.mapper.paper.EPaperQtypeMapper;
import com.xhkjedu.sexam.mapper.paperstudent.EPaperStudentMapper;
import com.xhkjedu.sexam.mapper.paperstudent.EPaperStudentQuestionMapper;
import com.xhkjedu.sexam.mapper.report.ERbaseMapper;
import com.xhkjedu.sexam.mapper.report.EReportGenerateMapper;
import com.xhkjedu.sexam.mapper.report.ERsubjectMapper;
import com.xhkjedu.sexam.mapper.reportclass.ERclassMapper;
import com.xhkjedu.sexam.mapper.reportclass.ERclassQtypeMapper;
import com.xhkjedu.sexam.mapper.reportclass.ERclassQuestionMapper;
import com.xhkjedu.sexam.mapper.reportclass.ERclassQuestionPointMapper;
import com.xhkjedu.sexam.mapper.reportstu.ERstudentMapper;
import com.xhkjedu.sexam.model.paperstudent.EPaperStudentQuestion;
import com.xhkjedu.sexam.model.report.ERbase;
import com.xhkjedu.sexam.model.report.ERsubject;
import com.xhkjedu.sexam.model.reportclass.ERclass;
import com.xhkjedu.sexam.model.reportclass.ERclassQtype;
import com.xhkjedu.sexam.model.reportclass.ERclassQuestion;
import com.xhkjedu.sexam.model.reportclass.ERclassQuestionPoint;
import com.xhkjedu.sexam.model.reportstu.ERstudent;
import com.xhkjedu.sexam.utils.ExamUtil;
import com.xhkjedu.sexam.vo.paper.EPaperQPointVo;
import com.xhkjedu.sexam.vo.paper.EPaperQtypeQuestionVo;
import com.xhkjedu.sexam.vo.paper.EPaperQtypeVo;
import com.xhkjedu.sexam.vo.report.ERClassScoreVo;
import com.xhkjedu.sexam.vo.report.ERPaperVo;
import com.xhkjedu.utils.N_Utils;
import org.bouncycastle.operator.AADProcessor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.DoubleSummaryStatistics;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author ywx
 * @classname EReportGenerateService
 * @description 考试报告生成
 * @date 2022/8/8 10:04
 **/
@Service
public class EReportGenerateService {
    @Resource
    private EReportGenerateMapper eReportGenerateMapper;
    @Resource
    private EClassMapper eClassMapper;
    @Resource
    private EPaperStudentMapper ePaperStudentMapper;
    @Resource
    private EPaperQtypeMapper ePaperQtypeMapper;
    @Resource
    private EPaperStudentQuestionMapper ePaperStudentQuestionMapper;
    @Resource
    private EPaperAnalyzeMapper ePaperAnalyzeMapper;


    @Resource
    private ERbaseMapper eRbaseMapper;
    @Resource
    private ERstudentMapper eRstudentMapper;
    @Resource
    private ERsubjectMapper eRsubjectMapper;
    @Resource
    private ERclassMapper eRclassMapper;
    @Resource
    private ERclassQtypeMapper eRclassQtypeMapper;
    @Resource
    private ERclassQuestionMapper eRclassQuestionMapper;
    @Resource
    private ERclassQuestionPointMapper eRclassQuestionPointMapper;


    //生成考试报告
    @Transactional(rollbackFor = Exception.class)
    public void generateExamReport(Integer examid) {
        //生成前先删除以前的考试报告
        eReportGenerateMapper.deleteExamReport(examid);
        //学生上次考试排名及目标
        List<ERstudent> stuRankGoals = eReportGenerateMapper.listStuRankAndGoal(examid);

        List<Map> classes = eClassMapper.listByExamId(examid);
        List<Map> subjects = eReportGenerateMapper.listSubject(examid);
        List<ERPaperVo> papers = eReportGenerateMapper.listPaper(examid);
        int classnum = classes.size();
        int stunum = classes.stream().mapToInt(m -> (int) m.get("classnum")).sum();
        int subjectnum = subjects.size();

        String subjectid;
        String subjectname;
        Map<String, String> subjectMap = subjects.stream().collect(Collectors.toMap(m -> m.get("subjectid").toString(),
                m -> m.get("subjectname").toString()));
        Map<String, ERPaperVo> paperMap = papers.stream().collect(Collectors.toMap(m -> m.getSubjectid(), m -> m));

        List<ERstudent> schoolStudents = new ArrayList<>();//学校学生成绩
        List<ERstudent> schoolSubjectStudents = new ArrayList<>();//学校科目学生成绩
        List<ERstudent> classStudents = new ArrayList<>();//班级学生成绩
        List<ERstudent> classSubjectStudents = new ArrayList<>();//班级科目学生成绩
        Map<String, Integer> schoolStuRank = new HashMap<>();//学校学生分数排名
        Map<String, Integer> schoolSubStuRank = new HashMap<>();//学校科目学生分数排名
        Map<String, Integer> classStuRank = new HashMap<>();//班级学生分数排名
        Map<String, Integer> classSubStuRank = new HashMap<>();//班级科目学生分数排名
        List<ERstudent> students = ePaperStudentMapper.listByExamId(examid);
        Map<Integer, List<ERstudent>> schoolCollect = students.stream().collect(Collectors.groupingBy(s -> s.getStudentid()));
        for (Map.Entry<Integer, List<ERstudent>> entry : schoolCollect.entrySet()) {
            Integer studentid = entry.getKey();
            ERstudent cs = new ERstudent();
            cs.setStudentid(studentid);
            cs.setScore(entry.getValue().stream().mapToDouble(s -> s.getScore()).sum());
            schoolStudents.add(cs);
        }
        Map<Integer, List<ERstudent>> cCollect = students.stream().collect(Collectors.groupingBy(s -> s.getClassid()));
        for (Map.Entry<Integer, List<ERstudent>> entry : cCollect.entrySet()) {
            Integer classid = entry.getKey();
            subjectid = "zf";
            subjectname = "总分";
            List<ERstudent> studentList = entry.getValue();

            Map<Integer, List<ERstudent>> sCollect = studentList.stream().collect(Collectors.groupingBy(s -> s.getStudentid()));
            for (Map.Entry<Integer, List<ERstudent>> csEntry : sCollect.entrySet()) {
                ERstudent cs = new ERstudent();
                cs.setClassid(classid);
                cs.setStudentid(csEntry.getKey());
                cs.setSubjectid(subjectid);
                cs.setSubjectname(subjectname);
                cs.setScore(csEntry.getValue().stream().mapToDouble(s -> s.getScore()).sum());
                classStudents.add(cs);
            }
            Map<String, List<ERstudent>> subCollect = studentList.stream().collect(Collectors.groupingBy(s -> s.getSubjectid()));
            for (Map.Entry<String, List<ERstudent>> ssEntry : subCollect.entrySet()) {
                subjectid = ssEntry.getKey();
                subjectname = subjectMap.get(subjectid);
                studentList = ssEntry.getValue();
                for (ERstudent cs : studentList) {
                    cs.setSubjectname(subjectname);
                    classSubjectStudents.add(cs);
                }
            }
        }

        DoubleSummaryStatistics schoolStatistics = schoolStudents.stream().mapToDouble(s -> s.getScore()).summaryStatistics();
        DoubleSummaryStatistics classStatistics = classStudents.stream().mapToDouble(s -> s.getScore()).summaryStatistics();
        DoubleSummaryStatistics cSStatistics = classSubjectStudents.stream().mapToDouble(s -> s.getScore()).summaryStatistics();
        double schoolStatisticsMax = schoolStatistics.getMax();
        double schoolStatisticsAverage = schoolStatistics.getAverage();
        double schoolStatisticsMin = schoolStatistics.getMin();

        ERbase rbase = new ERbase();
        rbase.setExamid(examid);
        rbase.setClassnum(classnum);
        rbase.setStunum(stunum);
        rbase.setMissnum(students.stream().filter(l -> l.getSstate() == 3)
                .map(l -> l.getStudentid()).distinct().collect(Collectors.toList()).size());
        rbase.setSubjectnum(subjectnum);
        rbase.setMaxscore(schoolStatisticsMax);
        rbase.setAvgscore(schoolStatisticsAverage);
        rbase.setMixscore(schoolStatisticsMin);
        eRbaseMapper.insertSelective(rbase);

        Map<String, List<ERstudent>> subCollect = students.stream().collect(Collectors.groupingBy(s -> s.getSubjectid()));
        List<ERsubject> subjectList = new ArrayList<>();//考试报告科目情况
        List<ERclass> classList = new ArrayList<>();//考试报告班级情况
        for (Map.Entry<String, List<ERstudent>> ssEntry : subCollect.entrySet()) {
            subjectid = ssEntry.getKey();
            subjectname = subjectMap.get(subjectid);
            List<ERstudent> list = ssEntry.getValue();
            Map<Integer, List<ERstudent>> sCollect = list.stream().collect(Collectors.groupingBy(s -> s.getStudentid()));
            for (Map.Entry<Integer, List<ERstudent>> csEntry : sCollect.entrySet()) {
                ERstudent cs = new ERstudent();
                cs.setClassid(0);
                cs.setStudentid(csEntry.getKey());
                cs.setSubjectid(subjectid);
                cs.setSubjectname(subjectname);
                cs.setScore(csEntry.getValue().stream().mapToDouble(s -> s.getScore()).sum());
                schoolSubjectStudents.add(cs);
            }
            ERPaperVo rp = paperMap.get(subjectid);
            Double allscore = rp.getPscore();//满分
            double yxscore = allscore * 0.85;//优秀分
            double lhscore = allscore * 0.7;//良好分
            double jgscore = allscore * 0.6;//及格分
            double dfscore = allscore * 0.4;//低分

            DoubleSummaryStatistics statistics = list.stream().mapToDouble(s -> s.getScore()).summaryStatistics();
            ERsubject rs = new ERsubject();
            rs.setExamid(examid);
            rs.setSubjectid(subjectid);
            rs.setSubjectname(subjectname);
            rs.setScore(allscore);
            rs.setMaxscore(statistics.getMax());
            rs.setMinscore(statistics.getMin());
            rs.setAvgscore(statistics.getAverage());
            int yxnum = list.stream().filter(l -> l.getScore().compareTo(yxscore) != -1)
                    .collect(Collectors.toList()).size();
            int lhnum = list.stream().filter(l -> l.getScore().compareTo(lhscore) != -1)
                    .collect(Collectors.toList()).size();
            int jgnum = list.stream().filter(l -> l.getScore().compareTo(jgscore) != -1)
                    .collect(Collectors.toList()).size();
            int dfnum = list.stream().filter(l -> l.getScore().compareTo(dfscore) != 1)
                    .collect(Collectors.toList()).size();
            List<Double> scores = list.stream().map(l -> l.getScore()).collect(Collectors.toList());
            rs.setYxrate(N_Utils.getIntegerDivideAndMulitiply(yxnum, stunum));
            rs.setLhrate(N_Utils.getIntegerDivideAndMulitiply(lhnum, stunum));
            rs.setJgrate(N_Utils.getIntegerDivideAndMulitiply(jgnum, stunum));
            rs.setDfrate(N_Utils.getIntegerDivideAndMulitiply(dfnum, stunum));
            rs.setBzc(ExamUtil.standardDiviation(scores));
            int sknum = list.size();
            rs.setStunum(sknum);//实考人数
            rs.setMissnum(stunum - sknum);//缺考人数=计划人数-实考人数
            subjectList.add(rs);

            Map<Integer, List<ERstudent>> claCollect = list.stream().collect(Collectors.groupingBy(s -> s.getClassid()));
            for (Map.Entry<Integer, List<ERstudent>> entry : claCollect.entrySet()) {
                Integer classid = entry.getKey();
                List<ERstudent> rstudentList = entry.getValue();
                DoubleSummaryStatistics claStatistics = rstudentList.stream().mapToDouble(s -> s.getScore()).summaryStatistics();
                ERclass rc = new ERclass();
                rc.setExamid(examid);
                rc.setClassid(classid);
                rc.setSubjectid(subjectid);
                rc.setSubjectname(subjectname);
                rc.setAllscore(allscore);
                rc.setClassmaxscore(claStatistics.getMax());
                rc.setClassminscore(claStatistics.getMin());
                rc.setClassavgscore(claStatistics.getAverage());
                rc.setSchoolmaxscore(statistics.getMax());
                rc.setSchoolavgscore(statistics.getAverage());
                sknum = rstudentList.size();
                rc.setStunum(sknum);//实考人数
                rc.setMissnum(stunum - sknum);//缺考人数=计划人数-实考人数
                yxnum = rstudentList.stream().filter(l -> l.getScore().compareTo(yxscore) != -1)
                        .collect(Collectors.toList()).size();
                lhnum = rstudentList.stream().filter(l -> l.getScore().compareTo(lhscore) != -1)
                        .collect(Collectors.toList()).size();
                jgnum = rstudentList.stream().filter(l -> l.getScore().compareTo(jgscore) != -1)
                        .collect(Collectors.toList()).size();
                dfnum = rstudentList.stream().filter(l -> l.getScore().compareTo(dfscore) != 1)
                        .collect(Collectors.toList()).size();
                scores = rstudentList.stream().map(l -> l.getScore()).collect(Collectors.toList());
                rc.setYxrate(N_Utils.getIntegerDivideAndMulitiply(yxnum, stunum));
                rc.setLhrate(N_Utils.getIntegerDivideAndMulitiply(lhnum, stunum));
                rc.setJgrate(N_Utils.getIntegerDivideAndMulitiply(jgnum, stunum));
                rc.setDfrate(N_Utils.getIntegerDivideAndMulitiply(dfnum, stunum));
                rc.setBzc(ExamUtil.standardDiviation(scores));
                classList.add(rc);
            }
        }

        eRclassMapper.insertList(classList);
        eRsubjectMapper.insertList(subjectList);

        setRank(schoolStudents, schoolStuRank, 1);//学校学生分数排名
        setRank(schoolSubjectStudents, schoolSubStuRank, 2);//学校科目学生分数排名
        setRank(classStudents, classStuRank, 3);//班级学生分数排名
        setRank(classSubjectStudents, classSubStuRank, 4);//班级科目学生分数排名

        for (ERstudent cs : classStudents) {
            Integer studentid = cs.getStudentid();
            cs.setClassrank(classStuRank.get(cs.getClassid() + "_" + studentid));
            cs.setClassmaxscore(classStatistics.getMax());
            cs.setClassavgscore(classStatistics.getAverage());
            Integer schoolrank = schoolStuRank.get(studentid);
            cs.setSchoolrank(schoolrank);
            cs.setSchoolmaxscore(schoolStatisticsMax);
            cs.setSchoolavgscore(schoolStatisticsAverage);
            setStuGoal(stuRankGoals, cs, schoolrank);//设置学生目标
        }
        eRstudentMapper.insertList(classStudents);

        DoubleSummaryStatistics sSStatistics = schoolSubjectStudents.stream().mapToDouble(s -> s.getScore()).summaryStatistics();
        for (ERstudent cs : classSubjectStudents) {
            Integer studentid = cs.getStudentid();
            Integer classid = cs.getClassid();
            subjectid = cs.getSubjectid();
            cs.setClassrank(classSubStuRank.get(classid + "_" + subjectid + "_" + studentid));
            cs.setClassmaxscore(cSStatistics.getMax());
            cs.setClassavgscore(cSStatistics.getAverage());
            Integer schoolrank = schoolSubStuRank.get(subjectid + "_" + studentid);
            cs.setSchoolrank(schoolrank);
            cs.setSchoolmaxscore(sSStatistics.getMax());
            cs.setSchoolavgscore(sSStatistics.getAverage());
            setStuGoal(stuRankGoals, cs, schoolrank);//设置学生目标
        }
        eRstudentMapper.insertList(classSubjectStudents);

        setClassQuestion(examid, subjects, classes);//题型试题
    }

    //设置学生目标
    private void setStuGoal(List<ERstudent> stuRankGoals, ERstudent cs, Integer schoolrank) {
        String goalparam = "0.2";
        ERstudent rg = stuRankGoals.stream().filter(s -> s.getStudentid().equals(cs.getStudentid())
                && s.getSubjectid().equals(cs.getSubjectid())).findFirst().orElse(null);
        Integer goal = 0;
        Integer nextgoal = 0;
        if (rg != null) {
            goal = rg.getNextgoal();
            nextgoal = ExamUtil.getUserGroupGoalByParam(schoolrank, goalparam);
        }
        cs.setGoal(goal);
        cs.setNextgoal(nextgoal);
    }

    //分数排名
    private void setRank(List<ERstudent> students, Map<String, Integer> rank, Integer code) {
        students =
                students.stream().sorted((s1, s2) -> -Double.compare(s1.getScore(), s2.getScore())).collect(Collectors.toList());
        List<Map.Entry<Double, List<ERstudent>>> gslist2 = students.stream()
                .collect(Collectors.groupingBy(ERstudent::getScore)).entrySet()
                .stream().sorted((s1, s2) -> -Double.compare(s1.getKey(), s2.getKey())).collect(Collectors.toList());
        Integer index = 1;
        String key;
        for (Map.Entry<Double, List<ERstudent>> entry : gslist2) {
            for (ERstudent cgs : entry.getValue()) {
                Integer studentid = cgs.getStudentid();
                Integer classid = cgs.getClassid();
                String subjectid = cgs.getSubjectid();
                if (code == 1) {//学校学生
                    key = studentid.toString();
                } else if (code == 2) {//学校科目学生
                    key = subjectid + "_" + studentid;
                } else if (code == 3) {//班级学生
                    key = classid + "_" + studentid;
                } else {//班级科目学生
                    key = classid + "_" + subjectid + "_" + studentid;
                }
                rank.put(key, index);
            }
            index = index + entry.getValue().size();
        }
    }

    //题型、试题、知识点
    private void setClassQuestion(Integer examid,List<Map> subjects,List<Map> classes){
        //考试所有学生提交试卷情况
        List<EPaperStudentQuestion> stulist = ePaperStudentQuestionMapper.listExamStudentsAnswer(examid);

        List<ERclassQtype> rtypelist = new ArrayList<>();
        List<ERclassQuestion> rqlist = new ArrayList<>();
        List<ERclassQuestionPoint> rpointlist = new ArrayList<>();

        for(Map map : subjects){
            String subjectid = map.get("subjectid").toString();
            Integer epid = Integer.parseInt(map.get("epid").toString());//获取试卷id
            Integer ptype = Integer.parseInt(map.get("ptype").toString());//试卷类型1题库2附件
            Double pscore = Double.parseDouble(map.get("pscore").toString());
            List<EPaperQtypeVo> fjtypelist = new ArrayList<>();
            if(ptype == 1){
                fjtypelist = ePaperQtypeMapper.listPaperQtypeQuestions(epid);//试卷题型试题信息（题库）
                setEPaperQtypeForQues(fjtypelist);
            }else{
                fjtypelist = ePaperQtypeMapper.listPaperQtypeQuesitonsForFj(epid);//试卷题型试题信息（附件）
            }

            //遍及试卷处理题型下各班级得分情况
            for(EPaperQtypeVo t : fjtypelist){
                Double eptscore = t.getEptscore();
                Double tgscore = 0.0;//题型下年级得分
                int stunum = 0;
                Map<Integer, ERClassScoreVo> tcmap = new HashMap<>();//题型下班级得分
                String qnstr = "";
                List<EPaperQtypeQuestionVo> questionVos = t.getQuestions();
                for(int i=0;i<questionVos.size();i++){
                    EPaperQtypeQuestionVo q = questionVos.get(i);
                    if (i ==0){
                        qnstr = q.getQn();
                    }else{
                        qnstr = qnstr + "," + q.getQn();
                    }


                    //获取指定试题试题得分
                    List<EPaperStudentQuestion> qstu = stulist.stream().filter(o -> o.getEpid().equals(t.getEpid())
                             && o.getEptqid().equals(q.getEptqid())).collect(Collectors.toList());
                    if(i == 0){
                        stunum = qstu.size();
                    }
                    EPaperStudentQuestion maxscoreStu = qstu.stream().max(Comparator.comparing(EPaperStudentQuestion::getStuscore)).get();//最高分
                    Double qgscore = qstu.stream().mapToDouble(EPaperStudentQuestion::getStuscore).sum();
                    Double qgavgscore = N_Utils.getDoubleDivideAndMulitiply(qgscore,qstu.size());//年级平均分
                    Double qgsrate = N_Utils.getDoubleDivideAndMulitiply(qgscore,q.getScore() * qstu.size());
                    tgscore = ExamUtil.add(tgscore,qgscore);

                    for(Map classm : classes){
                        Integer classid = Integer.parseInt(classm.get("classid").toString());
                        List<EPaperStudentQuestion> classStu = qstu.stream().filter(o -> o.getClassid().equals(classid)).collect(Collectors.toList());
                        EPaperStudentQuestion maxclassstu = classStu.stream().max(Comparator.comparing(EPaperStudentQuestion::getStuscore)).get();//最高分
                        Double qallstu = classStu.stream().mapToDouble(EPaperStudentQuestion::getStuscore).sum();
                        Double qcavgscore = N_Utils.getDoubleDivideAndMulitiply(qallstu,classStu.size());//年级平均分
                        Double qcsrate = N_Utils.getDoubleDivideAndMulitiply(qallstu,q.getScore() * classStu.size());

                        ERclassQuestion ercq = new ERclassQuestion();
                        ercq.setExamid(examid);
                        ercq.setClassid(classid);
                        ercq.setSubjectid(subjectid);
                        ercq.setEptqid(q.getEptqid());
                        ercq.setQn(q.getQn());
                        ercq.setQorder(q.getQorder());
                        if(ptype == 1){
                            ercq.setComplexity(q.getComplexity());
                        }
                        ercq.setClassmaxscore(maxclassstu.getStuscore());
                        ercq.setClassavgscore(qcavgscore);
                        ercq.setClasssrate(qcsrate);
                        ercq.setGrademaxscore(maxscoreStu.getStuscore());
                        ercq.setGradeavgscore(qgavgscore);
                        ercq.setGradesrate(qgsrate);
                        //处理单选题选项情况
                        Map stuansmap = setPaperQuestionsForStu(q,classStu);
                        ercq.setAnswerjson(stuansmap.get("answerlist").toString());
                        ercq.setGoodstujson(stuansmap.get("goodlist").toString());
                        ercq.setBadstujson(stuansmap.get("badlist").toString());
                        rqlist.add(ercq);//单个试题统计

                        if(tcmap.containsKey(classid)){
                            ERClassScoreVo erClassScoreVo = tcmap.get(classid);
                            if(i ==0){
                                erClassScoreVo.setStunum(classStu.size());
                                erClassScoreVo.setTcscore(0.0);
                            }
                            erClassScoreVo.setTcscore(ExamUtil.add(erClassScoreVo.getTcscore(), qallstu));

                        }else{
                            ERClassScoreVo erClassScoreVo = new ERClassScoreVo();
                            erClassScoreVo.setStunum(classStu.size());
                            erClassScoreVo.setTcscore(0.0);
                            erClassScoreVo.setTcscore(ExamUtil.add(erClassScoreVo.getTcscore(), qallstu));
                            tcmap.put(classid,erClassScoreVo);
                        }
                    }
                }

                Double tgavescore = N_Utils.getDoubleDivideAndMulitiply(tgscore,stunum);//题型下年级平均分
                Double tgsrate = N_Utils.getDoubleDivideAndMulitiply(tgscore,eptscore * stunum);//年级得分率

                for(Map.Entry<Integer,ERClassScoreVo> entry : tcmap.entrySet()){
                    ERClassScoreVo erClassScoreVo = entry.getValue();
                    ERclassQtype eRclassQtype = new ERclassQtype();
                    eRclassQtype.setExamid(examid);
                    eRclassQtype.setSubjectid(subjectid);
                    eRclassQtype.setEpid(epid);
                    eRclassQtype.setClassid(entry.getKey());
                    eRclassQtype.setQtypename(t.getEptname());
                    eRclassQtype.setQn(t.getEptorder().toString());
                    eRclassQtype.setScore(eptscore);
                    eRclassQtype.setNum(t.getEptnum());
                    eRclassQtype.setSrate(N_Utils.getDoubleDivideAndMulitiply(eptscore,pscore));
                    eRclassQtype.setGradeavgscore(tgavescore);
                    eRclassQtype.setGradesrate(tgsrate);
                    eRclassQtype.setClassavgscore(N_Utils.getDoubleDivideAndMulitiply(erClassScoreVo.getTcscore(),erClassScoreVo.getStunum()));
                    eRclassQtype.setClasssrate(N_Utils.getDoubleDivideAndMulitiply(erClassScoreVo.getTcscore(),eptscore * erClassScoreVo.getStunum() ));
                    eRclassQtype.setQn(qnstr);

                    rtypelist.add(eRclassQtype);
                }
            }

            //仅有题库试卷有知识点
            if(ptype == 1){
                //获取试卷只是分析
                Map epa = ePaperAnalyzeMapper.getPaperAnalzyeByEpid(epid);
                String pointjson = epa.get("pointjson").toString();
                List<Map> pointlist = JSON.parseArray(pointjson,Map.class);
                //遍历知识点处理年级班级知识点情况
                for(int j=0;j<pointlist.size();j++){
                    Map pointmap = pointlist.get(j);
                    String pointname = pointmap.get("pointname").toString();
                    Double score = Double.parseDouble(pointmap.get("score").toString());
                    Double scorerate = Double.parseDouble(pointmap.get("scorerate").toString());
                    String qnstr = pointmap.get("order").toString();

                    List<String> qnlst = JSON.parseArray(qnstr,String.class);//题号集合
                    List<EPaperStudentQuestion> gstus = stulist.stream().filter(o -> o.getEpid().equals(epid) && qnlst.contains(o.getQn())).collect(Collectors.toList());
                    Double gstuscore = gstus.stream().mapToDouble(EPaperStudentQuestion :: getStuscore).sum();
                    Double gscore = gstus.stream().mapToDouble(EPaperStudentQuestion :: getQscore).sum();
                    Double gavgscore = N_Utils.getDoubleDivideAndMulitiply(gstuscore,gstus.size());//平均分分
                    Double gsrate = N_Utils.getDoubleDivideAndMulitiply(gstuscore,gscore);//得分率
                    for(Map classm : classes){
                        Integer classid = Integer.parseInt(classm.get("classid").toString());
                        List<EPaperStudentQuestion> cstus = gstus.stream().filter( o -> o.getClassid().equals(classid)).collect(Collectors.toList());
                        Double cstuscore = cstus.stream().mapToDouble(EPaperStudentQuestion::getStuscore).sum();
                        Double cscore = cstus.stream().mapToDouble(EPaperStudentQuestion::getQscore).sum();
                        Double cavgscore = N_Utils.getDoubleDivideAndMulitiply(cstuscore,cstus.size());//平均分分
                        Double csrate = N_Utils.getDoubleDivideAndMulitiply(cstuscore,cscore);//得分率

                        ERclassQuestionPoint pointvo = new ERclassQuestionPoint();
                        pointvo.setExamid(examid);
                        pointvo.setClassid(classid);
                        pointvo.setEpid(epid);
                        pointvo.setSubjectid(subjectid);
                        pointvo.setPointname(pointname);
                        pointvo.setScore(score);
                        pointvo.setSrate(scorerate);
                        pointvo.setQns(qnstr);
                        pointvo.setGradeavgscore(gavgscore);
                        pointvo.setGradesrate(gsrate);
                        pointvo.setClassavgscore(cavgscore);
                        pointvo.setClasssrate(csrate);
                        rpointlist.add(pointvo);
                    }

                }

            }
        }
        eRclassQtypeMapper.insertList(rtypelist);
        eRclassQuestionMapper.insertList(rqlist);
        eRclassQuestionPointMapper.insertList(rpointlist);
    }
    //处理题库试卷中子母题
    private void setEPaperQtypeForQues(List<EPaperQtypeVo> fjtypelist){
        for(EPaperQtypeVo qt : fjtypelist){
            List<EPaperQtypeQuestionVo> qlist = qt.getQuestions();
            List<EPaperQtypeQuestionVo> rtnqlist = new ArrayList<>();//保存处理后的试题
            String qpid = "";//母题id
            List<EPaperQtypeQuestionVo> sonqlist = new ArrayList<>();
            for(EPaperQtypeQuestionVo q : qlist){
                //试题类型1单题2母题3子题
                if(q.getQlevel() == 3){
                    if(!q.getQuestionpid().equals(qpid)){
                        sonqlist = qlist.stream().filter(o -> o.getQuestionpid().equals(q.getQuestionpid())).collect(Collectors.toList());
                        EPaperQtypeQuestionVo mq = new EPaperQtypeQuestionVo();
                        mq.setQuestionid(q.getQuestionpid());
                        mq.setCtype(q.getMctype());
                        mq.setQtypeid(q.getMqtypeid());
                        mq.setQtypename(q.getMqtypename());
                        mq.setQstem(q.getMqstem());
                        mq.setComplexity(q.getMcomplexity());
                        mq.setQanalyze(q.getMqanalyze());
                        mq.setQanswer(q.getMqanswer());
                        mq.setQorder(q.getQorder());
                        mq.setQlevel(q.getMqlevel());
                        List<EPaperQPointVo> allpoint = new ArrayList<>();
                        for(EPaperQtypeQuestionVo sq : sonqlist){
                            List<EPaperQPointVo> sqpoints = sq.getPoints();
                            for(EPaperQPointVo p : sqpoints){
                                if(!isExistEPaperPoints(allpoint,p)){
                                    allpoint.add(p);
                                }
                            }
                        }
                        Double mscore = sonqlist.stream().collect(Collectors.summingDouble(EPaperQtypeQuestionVo:: getScore));
                        mq.setScore(mscore);
                        mq.setSonques(sonqlist);
                        mq.setPoints(allpoint);
                        rtnqlist.add(mq);
                    }
                    qpid = q.getQuestionpid();
                }else{
                    EPaperQtypeQuestionVo mq = new EPaperQtypeQuestionVo();
                    BeanUtils.copyProperties(q,mq);
                    mq.setCtype(mq.getCtype());
                    rtnqlist.add(mq);
                }
            }
            qt.setQuestions(rtnqlist);
        }

    }
    private boolean isExistEPaperPoints(List<EPaperQPointVo> allpoint,EPaperQPointVo p){
        for(EPaperQPointVo pvo : allpoint){
            if(p.getPointid().equals(pvo.getPointid())){
                return true;
            }
        }
        return false;
    }
    //处理学生选项情况和得分情况
    private Map setPaperQuestionsForStu(EPaperQtypeQuestionVo q,List<EPaperStudentQuestion> classStu){
        Map<String,List<Map>> answermap = new HashMap<>();
        List<Map> goodlist = new ArrayList<>();
        List<Map> badlist = new ArrayList<>();

        Double score8 = 0.0;
        Double score5 = 0.0;
        String key1 = "";
        String key2 = "";
        String key3 = "";

        for(int i=0;i<classStu.size();i++){
            EPaperStudentQuestion sq = classStu.get(i);
            String stuanswer = sq.getStuanswer();
            if(q.getCtype() == 1 || q.getCtype() == 2 || q.getCtype() == 4 || q.getCtype() == 5 || q.getCtype() == 6){
                String answeroption = "未选择";
                if(N_Utils.isNotEmpty(stuanswer)){
                    List<String> stuanswers = JSON.parseArray(stuanswer,String.class);
                    answeroption = stuanswers.get(0);
                }

                Map stumap = new HashMap();
                stumap.put("studentid",sq.getStudentid());
                stumap.put("stuname",sq.getStuname());
                if(answermap.containsKey(answeroption)){
                   List<Map> stulist = answermap.get(answeroption);
                   stulist.add(stumap);
                }else{
                    List<Map> stulist = new ArrayList<>();
                    stulist.add(stumap);
                    answermap.put(answeroption,stulist);
                }
            }else{
                //主观题
                if(i==0){
                    //处理分数分段对应,用于分数段[0，50%）   [50%，80%）,  [80%，100%]
                    score8 = ExamUtil.getScoreRateScore(q.getScore(),0.8);
                    score5 = ExamUtil.getScoreRateScore(q.getScore(),0.8);
                    key1 = score8+"-"+q.getScore();
                    key2 = score8 + "-" + score5;
                    key3 = score5 + "-" + 0;
                    answermap.put(key1,new ArrayList<>());
                    answermap.put(key2,new ArrayList<>());
                    answermap.put(key3,new ArrayList<>());
                }

                List<Map> stulist = null;
                if(sq.getStuscore()>=score8){
                    stulist = answermap.get(key1);
                }else if(sq.getStuscore() >= score5 && sq.getStuscore()<score8){
                    stulist = answermap.get(key2);
                }else{
                    stulist = answermap.get(key3);
                }

                Map stumap = new HashMap();
                stumap.put("studentid",sq.getStudentid());
                stumap.put("stuname",sq.getStuname());
                stulist.add(stumap);
            }

            if(sq.getGood() == 1){
                Map goodmap = new HashMap();
                goodmap.put("studentid",sq.getStudentid());
                goodmap.put("stuname",sq.getStuname());
                goodlist.add(goodmap);
            }
            if(sq.getBad() == 1){
                Map badmap = new HashMap();
                badmap.put("studentid",sq.getStudentid());
                badmap.put("stuname",sq.getStuname());
                badlist.add(badmap);
            }
        }

        Map rtnmap = new HashMap();
        rtnmap.put("answerlist",JSON.toJSONString(answermap));
        rtnmap.put("goodlist",JSON.toJSONString(goodlist));
        rtnmap.put("badlist",JSON.toJSONString(badlist));
        return rtnmap;
    }
}
