package com.xhkjedu.smarking.service.report.generate;

import com.alibaba.fastjson.JSON;
import com.xhkjedu.smarking.mapper.report.reportother.MsrReportparamMapper;
import com.xhkjedu.smarking.mapper.report.reportstu.MsrStudentMapper;
import com.xhkjedu.smarking.model.exam.MsClassStudent;
import com.xhkjedu.smarking.model.paper.MsPaper;
import com.xhkjedu.smarking.model.report.reportother.MsrReportparam;
import com.xhkjedu.smarking.model.report.reportstu.MsrStudent;
import com.xhkjedu.smarking.model.report.reportsubject.MsrSubject;
import com.xhkjedu.smarking.utils.MarkingUtil;
import com.xhkjedu.smarking.vo.report.reportother.SzJsonVo;
import com.xhkjedu.utils.N_Utils;
import org.springframework.stereotype.Service;

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

/**
 *@Description : 学生报告生成服务
 *@Author ywx
 *Date 2025/1/3 11:29
 **/
@Service
public class ReportGenerateStudentService {
    @Resource
    private MsrStudentMapper msrStudentMapper;
    @Resource
    private MsrReportparamMapper msrReportparamMapper;

    //保存学生成绩分析
    public List<MsrStudent> saveStudent(Integer examid, List<MsPaper> subjects, List<MsrStudent> paperStudents
            , List<MsClassStudent> students, Map<String, MsrSubject> subjectMap) {
        List<MsrStudent> msrStudents = new ArrayList<>();
        //等级参数
        List<MsrReportparam> djParams = msrReportparamMapper.listReportparamByRpbelong(examid, "subjectshow", "all");
        List<SzJsonVo> djList = new ArrayList<>();
        if (N_Utils.isListNotEmpty(djParams)) {
            djList = JSON.parseArray(djParams.get(0).getSzjson(), SzJsonVo.class);
        }

        double fullscore = subjects.stream().mapToDouble(MsPaper::getPscore).sum();
        List<MsrStudent> classStudents = new ArrayList<>();//班级学生成绩(总分)
        List<MsrStudent> classSubjectStudents = new ArrayList<>();//班级科目学生成绩
        Map<String, Integer> rsMap = new HashMap<>();//各科人数
        Map<Integer, List<MsrStudent>> schoolCollect = paperStudents.stream().collect(Collectors.groupingBy(MsrStudent::getStudentid));
        List<Double> zfScores = new ArrayList<>();
        rsMap.put("zf", schoolCollect.entrySet().size());
        for (Map.Entry<Integer, List<MsrStudent>> entry : schoolCollect.entrySet()) {
            List<MsrStudent> list = entry.getValue();
            Double stuscore = N_Utils.formatDouble(list.stream().mapToDouble(MsrStudent::getStuscore).sum(), 1);
            zfScores.add(stuscore);
        }
        Map<Double, Integer> zfpm = MarkingUtil.fspm(zfScores);//总分分数排名
        Map<String, Map<Double, Integer>> dkpm = new HashMap<>();//单科分数排名
        for (MsPaper subject : subjects) {
            String subjectid = subject.getSubjectid();
            List<Double> dkScores = paperStudents.stream().filter(s -> s.getSubjectid().equals(subjectid)).map(MsrStudent::getStuscore).collect(Collectors.toList());
            dkpm.put(subjectid, MarkingUtil.fspm(dkScores));
            rsMap.put(subjectid, dkScores.size());
        }

        List<MsrStudent> paperStudents2 = new ArrayList<>();
        Map<String, List<MsClassStudent>> sClassStudent = students.stream().collect(Collectors.groupingBy(s -> s.getSubjectid() + "_" + s.getStudentid()));
        for (MsrStudent paperStudent : paperStudents) {
            String subjectid = paperStudent.getSubjectid();
            Integer studentid = paperStudent.getStudentid();
            Double stuscore = paperStudent.getStuscore();
            Double fullscore1 = paperStudent.getFullscore();
            String key = subjectid + "_" + studentid;
            for (MsClassStudent student : sClassStudent.get(key)) {
                MsrStudent cs = new MsrStudent();
                cs.setExamid(examid);
                cs.setClassid(student.getClassid());
                cs.setStudentid(student.getStudentid());
                cs.setSubjectid(subjectid);
                cs.setStuscore(stuscore);
                cs.setFullscore(fullscore1);
                paperStudents2.add(cs);
            }
        }
        String subjectid;
        Map<String, Double> bjdfMap = new HashMap<>();//班级得分
        Map<Integer, List<MsrStudent>> cCollect = paperStudents2.stream().collect(Collectors.groupingBy(MsrStudent::getClassid));
        Map<String, Map<Double, Integer>> bkpm = new HashMap<>();//班级科目分数排名
        for (Map.Entry<Integer, List<MsrStudent>> entry : cCollect.entrySet()) {
            Integer classid = entry.getKey();
            subjectid = "zf";
            List<MsrStudent> studentList = entry.getValue();

            Map<Integer, List<MsrStudent>> sCollect = studentList.stream().collect(Collectors.groupingBy(MsrStudent::getStudentid));
            List<MsrStudent> rstudents = new ArrayList<>();
            int totalnum = rsMap.get(subjectid);
            List<Double> bkScores = new ArrayList<>();
            for (Map.Entry<Integer, List<MsrStudent>> csEntry : sCollect.entrySet()) {
                MsrStudent cs = new MsrStudent();
                cs.setExamid(examid);
                cs.setClassid(classid);
                cs.setStudentid(csEntry.getKey());
                cs.setSubjectid(subjectid);
                Double stuscore = N_Utils.formatDouble(csEntry.getValue().stream().mapToDouble(MsrStudent::getStuscore).sum(), 1);
                cs.setStuscore(stuscore);
                cs.setFullscore(fullscore);
                cs.setSchoolrank(zfpm.get(stuscore));
                cs.setHighschool(setHighSchool(studentList, stuscore, totalnum));
                rstudents.add(cs);
                bkScores.add(stuscore);
            }
            bkpm.put(classid + "_" + subjectid, MarkingUtil.fspm(bkScores));
            bjdfMap.put(classid + "_" + subjectid, rstudents.stream().mapToDouble(MsrStudent::getStuscore).sum());
            classStudents.addAll(rstudents);
            Map<String, List<MsrStudent>> subCollect = studentList.stream().collect(Collectors.groupingBy(MsrStudent::getSubjectid));
            for (Map.Entry<String, List<MsrStudent>> ssEntry : subCollect.entrySet()) {
                bkScores = new ArrayList<>();
                subjectid = ssEntry.getKey();
                rstudents = ssEntry.getValue();
                Map<Double, Integer> dk = dkpm.get(subjectid);
                totalnum = rsMap.get(subjectid);
                double csScore = 0;
                for (MsrStudent rstudent : rstudents) {
                    Double stuscore = rstudent.getStuscore();
                    rstudent.setSchoolrank(dk.get(stuscore));
                    rstudent.setHighschool(setHighSchool(rstudents, stuscore, totalnum));
                    csScore = MarkingUtil.add(csScore, stuscore);
                    bkScores.add(stuscore);
                }
                bkpm.put(classid + "_" + subjectid, MarkingUtil.fspm(bkScores));
                bjdfMap.put(classid + "_" + subjectid, csScore);
                classSubjectStudents.addAll(rstudents);
            }
        }
        //学生成绩分析
        for (MsrStudent student : classStudents) {
            setStudent(student, bkpm, bjdfMap, subjectMap, djList);
        }
        for (MsrStudent student : classSubjectStudents) {
            setStudent(student, bkpm, bjdfMap, subjectMap, djList);
        }
        msrStudents.addAll(classStudents);
        msrStudents.addAll(classSubjectStudents);
        if (N_Utils.isListNotEmpty(msrStudents)) msrStudentMapper.insertList(msrStudents);
        return msrStudents;
    }

    //超过年级百分比
    private Double setHighSchool(List<MsrStudent> studentList, Double stuscore, int totalnum) {
        long num1 = studentList.stream().filter(s -> s.getStuscore().compareTo(stuscore) == 0).count();
        long num2 = studentList.stream().filter(s -> s.getStuscore().compareTo(stuscore) > 0).count();
        int num = totalnum - N_Utils.obj2Int(num1) - N_Utils.obj2Int(num2);
        return N_Utils.getIntegerDivideAndMulitiply(num, totalnum);
    }

    //设置学生分析计算参数
    private void setStudent(MsrStudent student, Map<String, Map<Double, Integer>> bkpm
            , Map<String, Double> bjdfMap, Map<String, MsrSubject> subjectMap, List<SzJsonVo> djList) {
        String subjectid;
        Integer classid = student.getClassid();
        subjectid = student.getSubjectid();
        student.setClassrank(bkpm.get(classid + "_" + subjectid).get(student.getStuscore()));
        MsrSubject msrSubject = subjectMap.get(subjectid);
        Double pjf = msrSubject.getAvgscore();//年级平均分
        student.setBzf(MarkingUtil.bzf(bjdfMap.get(classid + "_" + subjectid), pjf, msrSubject.getBzc()));
        student.setCjl(MarkingUtil.cjl(student.getStuscore(), pjf));
        Integer totalnum = msrSubject.getTotalnum();
        double rankrate = MarkingUtil.div(student.getSchoolrank(), totalnum);
        student.setRankrate(rankrate);//个人成绩排名率=自己所在学科成绩分数的名次/总人数
        student.setXkqrz(MarkingUtil.sub(msrSubject.getAvgrank(), rankrate));//学科强弱值 = 平均成绩排名率- 个人成绩排名率
        double dfv = N_Utils.getDoubleDivideAndMulitiply(student.getStuscore(), msrSubject.getFullscore());
        student.setGradevalue(MarkingUtil.dj(dfv, djList));
    }

}
