package com.qmth.distributed.print.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.qmth.distributed.print.business.bean.dto.report.*;
import com.qmth.distributed.print.business.bean.result.FinalScoreResult;
import com.qmth.distributed.print.business.bean.result.report.studentRequirement.*;
import com.qmth.distributed.print.business.entity.*;
import com.qmth.distributed.print.business.mapper.TRExamStudentMapper;
import com.qmth.distributed.print.business.service.*;
import com.qmth.teachcloud.common.contant.SystemConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * <p>
 * 报告考生表 服务实现类
 * </p>
 *
 * @author wangliang
 * @since 2024-02-18
 */
@Service
public class TRExamStudentServiceImpl extends ServiceImpl<TRExamStudentMapper, TRExamStudent> implements TRExamStudentService {
    private final static Logger log = LoggerFactory.getLogger(TRExamStudentServiceImpl.class);

    @Resource
    TRExamStudentService trExamStudentService;

    @Resource
    TRBasicInfoService trBasicInfoService;
    @Resource
    private ObeCourseTargetService obeCourseTargetService;
    @Resource
    private ObeCultureProgramRequirementService obeCultureProgramRequirementService;
    @Resource
    private ObeCourseRequirementReportService obeCourseRequirementReportService;

    /**
     * 获取考生详细报告
     *
     * @param trBasicInfo
     * @param paramsMap
     * @return
     */
    @Override
    @Transactional
    public List<ReportExamStudentDto> getExamStudentReportDetail(TRBasicInfo trBasicInfo, Map<String, Object> paramsMap) {
        List<ReportExamStudentDto> examStudentList = (List<ReportExamStudentDto>) paramsMap.get("examStudentList");
//        Map<String, Map<Long, Map<Long, DimensionDto>>> finalScoreExamStudentDimensionMap = (Map<String, Map<Long, Map<Long, DimensionDto>>>) paramsMap.get("finalScoreExamStudentDimensionMap");
        Map<String, FinalScoreResult> finalScoreResultMap = (Map<String, FinalScoreResult>) paramsMap.get("finalScoreResultMap");
        Map<String, Map<Long, Double>> finalScoreExamStudentTargetMap = (Map<String, Map<Long, Double>>) paramsMap.get("finalScoreExamStudentTargetMap");
        Map<Long, CourseTargetWordDto> targetWordMap = (Map<Long, CourseTargetWordDto>) paramsMap.get("targetWordMap");
        if (!CollectionUtils.isEmpty(examStudentList)) {
            List<TRExamStudent> trExamStudentList = new ArrayList<>(examStudentList.size());
            Map<Long, ReportExamStudentTargetDto> reportExamStudentTargetDtoMap = new LinkedHashMap<>();
            for (ReportExamStudentDto reportExamStudentDto : examStudentList) {
//                Map<Long, Map<Long, DimensionDto>> map = finalScoreExamStudentDimensionMap.get(reportExamStudentDto.getStudentCode());
                Map<Long, Double> map = finalScoreExamStudentTargetMap.get(reportExamStudentDto.getStudentCode());
                FinalScoreResult finalScoreResult = finalScoreResultMap.get(reportExamStudentDto.getStudentCode());
                ReportExamStudentUsualScoreDto reportExamStudentUsualScoreSumDto = finalScoreResult.getUsualScoreDto();
                map.forEach((k, v) -> {
                    List<ReportExamStudentTargetDto> targetList = CollectionUtils.isEmpty(reportExamStudentDto.getTargetList()) ? new ArrayList<>() : reportExamStudentDto.getTargetList();
                    if (targetWordMap.containsKey(k)) {
                        List<ReportExamStudentUsualScoreObjDto> scoreObjDtoList = reportExamStudentUsualScoreSumDto.getScoreMap().get(k);
                        if (!CollectionUtils.isEmpty(scoreObjDtoList)) {
                            CourseTargetWordDto courseTargetWordDto = targetWordMap.get(k);
//                            ReportExamStudentFinalScoreDto reportExamStudentFinalScoreDto = new ReportExamStudentFinalScoreDto(courseTargetWordDto.getFinalScoreDto(), finalScoreResult.getFinalScoreTarget().get(k));
//                            ReportExamStudentUsualScoreDto reportExamStudentUsualScoreDto = new ReportExamStudentUsualScoreDto(courseTargetWordDto.getUsualScoreDto().getUsualScoreTargetSumWeight(), scoreObjDtoList);

                            ReportExamStudentFinalScoreDto reportExamStudentFinalScoreDto = Objects.nonNull(courseTargetWordDto.getFinalScoreDto()) ? new ReportExamStudentFinalScoreDto(courseTargetWordDto.getFinalScoreDto(), finalScoreResult.getFinalScoreTarget().get(k)) : null;
                            ReportExamStudentUsualScoreDto reportExamStudentUsualScoreDto = new ReportExamStudentUsualScoreDto(scoreObjDtoList);

                            BigDecimal targetMatrixSumScore = new BigDecimal(0);
                            AtomicReference<BigDecimal> matrixDegree = new AtomicReference<>(new BigDecimal(0));
                            if (!reportExamStudentTargetDtoMap.containsKey(k)) {
                                Double targetMatrixScore = 0.0d;
                                if (Objects.nonNull(courseTargetWordDto.getFinalScoreDto())) {
                                    //old卷面分*权重/100
                                    //new卷面分/目标分
//                                    targetMatrixScore = new BigDecimal(v).divide(courseTargetWordDto.getFinalScoreDto().getFinalScoreTargetSumScore()).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                                    //卷面分*权重/100
                                    targetMatrixScore = new BigDecimal(v).multiply(courseTargetWordDto.getFinalScoreDto().getFinalScoreSumWeight()).divide(SystemConstant.PERCENT, 2, BigDecimal.ROUND_HALF_UP).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
                                    BigDecimal bigDecimal = new BigDecimal(v).setScale(2, BigDecimal.ROUND_HALF_UP);
                                    BigDecimal targetEvaluationValue = bigDecimal.divide(courseTargetWordDto.getFinalScoreDto().getFinalScoreTargetSumScore(), 2, BigDecimal.ROUND_HALF_UP).multiply(courseTargetWordDto.getFinalScoreDto().getFinalScoreSumWeight().divide(courseTargetWordDto.getTargetSumWeight(), 2, BigDecimal.ROUND_HALF_UP)).setScale(2, BigDecimal.ROUND_HALF_UP);
                                    matrixDegree.set(matrixDegree.get().add(targetEvaluationValue));
                                }
                                targetMatrixSumScore = targetMatrixSumScore.add(new BigDecimal(targetMatrixScore)).setScale(2, BigDecimal.ROUND_HALF_UP);
                                reportExamStudentDto.setScore(reportExamStudentDto.getScore() + targetMatrixScore);
                                //平时作业总和+累加
                                for (ReportExamStudentUsualScoreObjDto r : scoreObjDtoList) {
                                    BigDecimal bigDecimal = new BigDecimal(r.getScore()).setScale(2, BigDecimal.ROUND_HALF_UP);
                                    BigDecimal targetEvaluationValue = bigDecimal.divide(r.getTargetScore(), 2, BigDecimal.ROUND_HALF_UP).multiply(r.getTargetWeight().divide(courseTargetWordDto.getTargetSumWeight(), 2, BigDecimal.ROUND_HALF_UP)).setScale(2, BigDecimal.ROUND_HALF_UP);
                                    matrixDegree.set(matrixDegree.get().add(targetEvaluationValue));
                                }
                                Double usualMatrixSumScore = scoreObjDtoList.stream().mapToDouble(ReportExamStudentUsualScoreObjDto::getMatrixScore).sum();
                                reportExamStudentDto.setScore(reportExamStudentDto.getScore() + usualMatrixSumScore);
                                ReportExamStudentFinalScoreDto reportExamStudentFinalScoreTempDto = null;
                                if (Objects.nonNull(reportExamStudentFinalScoreDto)) {
                                    reportExamStudentFinalScoreDto.setTargetMatrixSumScore(targetMatrixSumScore.doubleValue());
                                    reportExamStudentFinalScoreTempDto = new ReportExamStudentFinalScoreDto(courseTargetWordDto.getFinalScoreDto(), targetMatrixSumScore.doubleValue(), finalScoreResult.getFinalScoreTarget().get(k));
                                }
//                                ReportExamStudentTargetDto reportExamStudentTargetDto = new ReportExamStudentTargetDto(courseTargetWordDto, reportExamStudentFinalScoreTempDto, new ReportExamStudentUsualScoreDto(courseTargetWordDto.getUsualScoreDto().getUsualScoreTargetSumWeight(), scoreObjDtoList.stream().map(ReportExamStudentUsualScoreObjDto::new).collect(Collectors.toList())));
                                ReportExamStudentTargetDto reportExamStudentTargetDto = new ReportExamStudentTargetDto(courseTargetWordDto, reportExamStudentFinalScoreTempDto, new ReportExamStudentUsualScoreDto(scoreObjDtoList.stream().map(ReportExamStudentUsualScoreObjDto::new).collect(Collectors.toList())), matrixDegree.get());
                                reportExamStudentTargetDtoMap.put(k, reportExamStudentTargetDto);
                            } else {
                                ReportExamStudentTargetDto reportExamStudentTargetDto = reportExamStudentTargetDtoMap.get(k);
                                ReportExamStudentFinalScoreDto reportExamStudentFinalScoreAvgDto = null;
                                Double targetMatrixScore = 0.0d;
                                if (Objects.nonNull(reportExamStudentTargetDto.getFinalScore())) {
                                    reportExamStudentFinalScoreAvgDto = reportExamStudentTargetDto.getFinalScore();
                                    targetMatrixScore = new BigDecimal(v).multiply(courseTargetWordDto.getFinalScoreDto().getFinalScoreSumWeight()).divide(SystemConstant.PERCENT, 2, BigDecimal.ROUND_HALF_UP).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

                                    BigDecimal bigDecimal = new BigDecimal(v).setScale(2, BigDecimal.ROUND_HALF_UP);
                                    BigDecimal targetEvaluationValue = bigDecimal.divide(courseTargetWordDto.getFinalScoreDto().getFinalScoreTargetSumScore(), 2, BigDecimal.ROUND_HALF_UP).multiply(courseTargetWordDto.getFinalScoreDto().getFinalScoreSumWeight().divide(courseTargetWordDto.getTargetSumWeight(), 2, BigDecimal.ROUND_HALF_UP)).setScale(2, BigDecimal.ROUND_HALF_UP);
                                    matrixDegree.set(matrixDegree.get().add(targetEvaluationValue));
                                    reportExamStudentTargetDto.setMatrixDegree(matrixDegree.get());
                                }
                                targetMatrixSumScore = targetMatrixSumScore.add(new BigDecimal(targetMatrixScore)).setScale(2, BigDecimal.ROUND_HALF_UP);
                                reportExamStudentDto.setScore(reportExamStudentDto.getScore() + targetMatrixScore);

                                if (Objects.nonNull(reportExamStudentFinalScoreDto)) {
                                    reportExamStudentFinalScoreDto.setTargetMatrixSumScore(targetMatrixSumScore.doubleValue());
                                    reportExamStudentFinalScoreAvgDto.setTargetMatrixSumScore(new BigDecimal(reportExamStudentFinalScoreAvgDto.getTargetMatrixSumScore()).add(targetMatrixSumScore).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                                }
                                ReportExamStudentUsualScoreDto reportExamStudentUsualScoreAvgDto = reportExamStudentTargetDto.getUsualScore();

                                //平时作业总和+累加
                                List<ReportExamStudentUsualScoreObjDto> reportExamStudentUsualScoreObjDtoList = reportExamStudentUsualScoreDto.getScoreList();
                                List<ReportExamStudentUsualScoreObjDto> reportExamStudentUsualScoreObjAvgDtoList = reportExamStudentUsualScoreAvgDto.getScoreList();
                                for (int i = 0; i < reportExamStudentUsualScoreObjDtoList.size(); i++) {
                                    ReportExamStudentUsualScoreObjDto reportExamStudentUsualScoreObjDto = reportExamStudentUsualScoreObjDtoList.get(i);
                                    reportExamStudentDto.setScore(reportExamStudentDto.getScore() + reportExamStudentUsualScoreObjDto.getMatrixScore());
                                    BigDecimal bigDecimal = new BigDecimal(reportExamStudentUsualScoreObjDto.getScore()).setScale(2, BigDecimal.ROUND_HALF_UP);
                                    BigDecimal targetEvaluationValue = bigDecimal.divide(reportExamStudentUsualScoreObjDto.getTargetScore(), 2, BigDecimal.ROUND_HALF_UP).multiply(reportExamStudentUsualScoreObjDto.getTargetWeight().divide(courseTargetWordDto.getTargetSumWeight(), 2, BigDecimal.ROUND_HALF_UP)).setScale(2, BigDecimal.ROUND_HALF_UP);
                                    matrixDegree.set(matrixDegree.get().add(targetEvaluationValue));
                                    reportExamStudentUsualScoreObjAvgDtoList.get(i).setMatrixScore(new BigDecimal(reportExamStudentUsualScoreObjAvgDtoList.get(i).getMatrixScore()).add(new BigDecimal(reportExamStudentUsualScoreObjDto.getMatrixScore())).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                                }
                                reportExamStudentTargetDtoMap.put(k, reportExamStudentTargetDto);
                            }
                            targetList.add(new ReportExamStudentTargetDto(courseTargetWordDto, reportExamStudentFinalScoreDto, reportExamStudentUsualScoreDto, matrixDegree.get()));
                        }
                    }
                    reportExamStudentDto.setTargetList(targetList);
                });
                reportExamStudentDto.setScore(new BigDecimal(reportExamStudentDto.getScore()).setScale(1, BigDecimal.ROUND_DOWN).doubleValue());
                Collections.sort(reportExamStudentDto.getTargetList());
                trExamStudentList.add(new TRExamStudent(trBasicInfo.getId(), reportExamStudentDto));
            }
            //加入目标分&平均分&各课程目标平均分
            BigDecimal size = new BigDecimal(examStudentList.size());
            List<ReportExamStudentTargetDto> targetDtoList = this.targetDtoParams(reportExamStudentTargetDtoMap, size);
            AtomicReference<Double> targetScoreSum = new AtomicReference<>(0.0d);
            AtomicReference<Double> usualScoreSum = new AtomicReference<>(0.0d);
            targetDtoList.stream().peek(e -> {
                targetScoreSum.set(targetScoreSum.get() + (Objects.nonNull(e.getFinalScore()) ? e.getFinalScore().getMatrixAvgScore() : 0.0d));
                usualScoreSum.set(usualScoreSum.get() + e.getUsualScore().getScoreList().stream().mapToDouble(ReportExamStudentUsualScoreObjDto::getMatrixAvgScore).sum());
            }).collect(Collectors.toList());

            Double score = new BigDecimal(targetScoreSum.get()).add(new BigDecimal(usualScoreSum.get())).setScale(1, BigDecimal.ROUND_DOWN).doubleValue();
            ReportExamStudentDto reportExamStudentTargetDto = new ReportExamStudentDto("目标分", "目标分", null, 100.d, targetDtoList);
            ReportExamStudentDto reportExamStudentAvgDto = new ReportExamStudentDto("平均分", "平均分", null, score, targetDtoList);
            ReportExamStudentDto reportExamStudentTargetAvgDto = new ReportExamStudentDto("各课程目标平均分", "各课程目标平均分", null, null, targetDtoList);

            examStudentList.addAll(Arrays.asList(reportExamStudentTargetDto, reportExamStudentAvgDto, reportExamStudentTargetAvgDto));
            trExamStudentList.addAll(Arrays.asList(new TRExamStudent(trBasicInfo.getId(), reportExamStudentTargetDto), new TRExamStudent(trBasicInfo.getId(), reportExamStudentAvgDto), new TRExamStudent(trBasicInfo.getId(), reportExamStudentTargetAvgDto)));
            this.remove(new QueryWrapper<TRExamStudent>().lambda().eq(TRExamStudent::getrBasicInfoId, trBasicInfo.getId()));
            this.saveBatch(trExamStudentList);
        }
        return examStudentList;
    }

    /**
     * 根据报告id删除数据
     *
     * @param rBasicInfoId
     * @return
     */
    @Override
    @Transactional
    public Boolean remove(Long rBasicInfoId) {
        return trExamStudentService.remove(new QueryWrapper<TRExamStudent>().lambda().eq(TRExamStudent::getrBasicInfoId, rBasicInfoId));
    }

    /**
     * 根据考试id/课程编码/试卷编码删除数据
     *
     * @param examId
     * @param courseCode
     * @param paperNumber
     * @param obeCourseOutlineId
     * @return
     */
    @Override
    @Transactional
    public Boolean remove(Long examId, String courseCode, String paperNumber, Long obeCourseOutlineId) {
        TRBasicInfo trBasicInfo = trBasicInfoService.queryBasicInfo(examId, courseCode, paperNumber, obeCourseOutlineId);
        return Objects.nonNull(trBasicInfo) ? trExamStudentService.remove(trBasicInfo.getId()) : false;
    }

    @Override
    public StudentRequirement getRequirementsStudentReport(Long cultureProgramId, String studentCode, Long semesterId) {

        List<StudentCourseInfoDto> studentCourseInfoDtoList = this.baseMapper.listStudentCourseByCultureProgramIdAndStudentCodeAndSemesterId(cultureProgramId, studentCode, semesterId);
        for (StudentCourseInfoDto studentCourseInfoDto : studentCourseInfoDtoList) {
            studentCourseInfoDto.setCourseTargetRequirementList(getRequirementsStudentReport(cultureProgramId));
            String resultDetail = studentCourseInfoDto.getResultDetail();
            if (!StringUtils.isEmpty(resultDetail)) {
                List<ReportExamStudentTargetDto> reportExamStudentTargetDtoList = JSON.parseArray(resultDetail, ReportExamStudentTargetDto.class);
                // 指标点
                for (ReportExamStudentTargetDto reportExamStudentTargetDto : reportExamStudentTargetDtoList) {
                    ObeCourseTarget obeCourseTarget = obeCourseTargetService.getById(reportExamStudentTargetDto.getTargetId());
                    for (CourseTargetRequirement courseTargetRequirement : studentCourseInfoDto.getCourseTargetRequirementList()) {
                        if (courseTargetRequirement.getSubRequirementId().equals(obeCourseTarget.getObeCultureProgramRequirementId())) {
                            courseTargetRequirement.setCourseTargetDegree(reportExamStudentTargetDto.getMatrixDegree().doubleValue());
                        } else {
                            courseTargetRequirement.setCourseTargetDegree(courseTargetRequirement.getCourseTargetDegree() != null ? courseTargetRequirement.getCourseTargetDegree() : 0.0d);
                        }
                    }
                }
            }
        }

        StudentRequirement studentRequirement = new StudentRequirement();
        // 各科目达成度
        List<StudentCourseRequirement> studentCourseRequirementList = new ArrayList<>();
        for (StudentCourseInfoDto studentCourseInfoDto : studentCourseInfoDtoList) {
            StudentCourseRequirement studentCourseRequirement = new StudentCourseRequirement();
            studentCourseRequirement.setCourseCode(studentCourseInfoDto.getCourseCode());
            studentCourseRequirement.setCourseName(studentCourseInfoDto.getCourseName());
            studentCourseRequirement.setSemesterName(studentCourseInfoDto.getSemesterName());
            studentCourseRequirement.setScore(studentCourseInfoDto.getScore());
            LinkedHashMap<String, Double> map = studentCourseInfoDto.getCourseTargetRequirementList().stream().collect(Collectors.toMap(CourseTargetRequirement::getRequirementName, CourseTargetRequirement::getCourseTargetDegree, (v1, v2) -> v1 != 0 && v2 != 0 ? v1.doubleValue() <= v2.doubleValue() ? v1 : v2 : v1 == 0 && v2 != 0 ? v2 : v1 != 0 && v2 == 0 ? v1 : null, LinkedHashMap::new));
            List<StudentCourseRequirementDetail> requirementDetailList = map.entrySet().stream().map(entry -> new StudentCourseRequirementDetail(entry.getKey(), entry.getValue())).collect(Collectors.toList());
            studentCourseRequirement.setRequirementDetailList(requirementDetailList);
            studentCourseRequirementList.add(studentCourseRequirement);
        }
        studentRequirement.setStudentCourseRequirementList(studentCourseRequirementList);

        // 汇总达成度
        List<CourseTargetRequirement> courseTargetRequirementListAll = new ArrayList<>();
        for (StudentCourseInfoDto studentCourseInfoDto : studentCourseInfoDtoList) {
            courseTargetRequirementListAll.addAll(studentCourseInfoDto.getCourseTargetRequirementList().stream().filter(m -> m.getCourseTargetDegree() != null).collect(Collectors.toList()));
        }

        Map<String, BigDecimal> requirementDegreeMap = new HashMap<>();
        ObeCourseRequirementReport obeCourseRequirementReport = obeCourseRequirementReportService.findByCultureProgramId(cultureProgramId);
        if (obeCourseRequirementReport != null) {
            ObeCourseRequirementDto obeCourseRequirementDto = JSON.parseObject(obeCourseRequirementReport.getRequirementDetail(), ObeCourseRequirementDto.class);
            requirementDegreeMap = obeCourseRequirementDto.getObeRequirements().stream().collect(Collectors.toMap(ObeRequirementDto::getName, ObeRequirementDto::getMatrixDegree));
        }

        Map<String, List<CourseTargetRequirement>> stringDoubleMap = courseTargetRequirementListAll.stream().collect(Collectors.groupingBy(m -> m.getRequirementSortNum() + "##" + m.getRequirementName()));
        List<StudentTotalRequirement> studentTotalRequirementList = new ArrayList<>();
        for (Map.Entry<String, List<CourseTargetRequirement>> entry : stringDoubleMap.entrySet()) {
            String[] keys = entry.getKey().split("##");
            Map<Long, Double> doubleMap = entry.getValue().stream().collect(Collectors.groupingBy(CourseTargetRequirement::getSubRequirementId, Collectors.averagingDouble(CourseTargetRequirement::getCourseTargetDegree)));
            StudentTotalRequirement studentTotalRequirement = new StudentTotalRequirement();
            studentTotalRequirement.setRequirementName(keys[1]);
            studentTotalRequirement.setRequirementSortNum(Integer.valueOf(keys[0]));
            studentTotalRequirement.setStudentDegree(doubleMap.values().stream().min(Double::compare).get());
            if (requirementDegreeMap.containsKey(keys[1])) {
                studentTotalRequirement.setProfessionalDegree(requirementDegreeMap.get(keys[1]).doubleValue());
            }
            studentTotalRequirementList.add(studentTotalRequirement);
        }
        studentTotalRequirementList.sort(Comparator.comparing(StudentTotalRequirement::getRequirementSortNum));
        studentRequirement.setStudentTotalRequirementList(studentTotalRequirementList);
        return studentRequirement;
    }

    private List<CourseTargetRequirement> getRequirementsStudentReport(Long cultureProgramId) {
        List<CourseTargetRequirement> courseTargetRequirementList = new ArrayList<>();
        List<ObeCultureProgramRequirement> obeCultureProgramRequirementList = obeCultureProgramRequirementService.listRequirement(cultureProgramId);
        for (ObeCultureProgramRequirement obeCultureProgramRequirement : obeCultureProgramRequirementList) {
            for (ObeCultureProgramRequirement cultureProgramRequirement : obeCultureProgramRequirement.getSubRequirementList()) {
                courseTargetRequirementList.add(new CourseTargetRequirement(cultureProgramRequirement.getId(), obeCultureProgramRequirement.getId(), obeCultureProgramRequirement.getName(), obeCultureProgramRequirement.getSortNum()));
            }
        }
        return courseTargetRequirementList;
    }

    @Override
    public IPage<StudentRequirementInfoDto> getRequirementsStudentPage(Long cultureProgramId, String studentCodeOrName, Integer pageNumber, Integer pageSize) {
        return this.baseMapper.requirementStudentPage(new Page<>(pageNumber, pageSize), cultureProgramId, studentCodeOrName);
    }

//    /**
//     * 知识点纬度数据构建
//     *
//     * @param map
//     * @param targetWordMap
//     * @param reportExamStudentDto
//     * @param reportExamStudentUsualScoreSumDto
//     * @param reportExamStudentTargetDtoMap
//     * @param finalScoreResult
//     */
//    protected void dimensionDataBuild(Map<Long, Map<Long, DimensionDto>> map, Map<Long, CourseTargetWordDto> targetWordMap,
//                                      ReportExamStudentDto reportExamStudentDto, ReportExamStudentUsualScoreDto reportExamStudentUsualScoreSumDto,
//                                      Map<Long, ReportExamStudentTargetDto> reportExamStudentTargetDtoMap, FinalScoreResult finalScoreResult) {
//        //课程目标循环
//        map.forEach((k, v) -> {
//            List<DimensionDto> dimensionDtoList = new ArrayList<>(v.values());
//            Collections.sort(dimensionDtoList);
//            List<ReportExamStudentTargetDto> targetList = CollectionUtils.isEmpty(reportExamStudentDto.getTargetList()) ? new ArrayList<>() : reportExamStudentDto.getTargetList();
//            if (targetWordMap.containsKey(k)) {
//                List<ReportExamStudentUsualScoreObjDto> scoreObjDtoList = reportExamStudentUsualScoreSumDto.getScoreMap().get(k);
//                CourseTargetWordDto courseTargetWordDto = targetWordMap.get(k);
//                ReportExamStudentFinalScoreDto reportExamStudentFinalScoreDto = new ReportExamStudentFinalScoreDto(courseTargetWordDto.getFinalScoreDto(), dimensionDtoList, finalScoreResult.getFinalScoreDimension().get(k));
//                ReportExamStudentUsualScoreDto reportExamStudentUsualScoreDto = new ReportExamStudentUsualScoreDto(scoreObjDtoList);
//
//                BigDecimal dimensionMatrixSumScore = new BigDecimal(0);
//                if (!reportExamStudentTargetDtoMap.containsKey(k)) {
//                    //各知识点转换分数
//                    for (DimensionDto dimensionDto : dimensionDtoList) {
//                        Double matrixScore = new BigDecimal(dimensionDto.getDimensionScore()).multiply(courseTargetWordDto.getFinalScoreDto().getFinalScoreSumWeight()).divide(SystemConstant.PERCENT, 2, BigDecimal.ROUND_HALF_UP).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
//                        dimensionDto.setDimensionMatrixScore(matrixScore);
//                        dimensionMatrixSumScore = dimensionMatrixSumScore.add(new BigDecimal(matrixScore)).setScale(2, BigDecimal.ROUND_HALF_UP);
//                        reportExamStudentDto.setScore(reportExamStudentDto.getScore() + matrixScore);
//                    }
//                    //平时作业总和+累加
//                    Double usualMatrixSumScore = scoreObjDtoList.stream().mapToDouble(ReportExamStudentUsualScoreObjDto::getMatrixScore).sum();
//                    reportExamStudentDto.setScore(reportExamStudentDto.getScore() + usualMatrixSumScore);
//                    reportExamStudentFinalScoreDto.setTargetDimensionMatrixSumScore(dimensionMatrixSumScore.doubleValue());
//                    ReportExamStudentFinalScoreDto reportExamStudentFinalScoreTempDto = new ReportExamStudentFinalScoreDto(courseTargetWordDto.getFinalScoreDto(), dimensionDtoList.stream().map(DimensionDto::new).collect(Collectors.toList()), dimensionMatrixSumScore.doubleValue(), finalScoreResult.getFinalScoreDimension().get(k));
//                    ReportExamStudentTargetDto reportExamStudentTargetDto = new ReportExamStudentTargetDto(courseTargetWordDto, reportExamStudentFinalScoreTempDto, new ReportExamStudentUsualScoreDto(scoreObjDtoList.stream().map(ReportExamStudentUsualScoreObjDto::new).collect(Collectors.toList())));
//                    reportExamStudentTargetDtoMap.put(k, reportExamStudentTargetDto);
//                } else {
//                    ReportExamStudentTargetDto reportExamStudentTargetDto = reportExamStudentTargetDtoMap.get(k);
//                    ReportExamStudentFinalScoreDto reportExamStudentFinalScoreAvgDto = reportExamStudentTargetDto.getFinalScore();
//                    List<DimensionDto> dimensionDtos = reportExamStudentFinalScoreAvgDto.getDimensionList();
//                    //各知识点转换分数
//                    for (int i = 0; i < dimensionDtoList.size(); i++) {
//                        DimensionDto dimensionDto = dimensionDtoList.get(i);
//                        Double matrixScore = new BigDecimal(dimensionDto.getDimensionScore()).multiply(courseTargetWordDto.getFinalScoreDto().getFinalScoreSumWeight()).divide(SystemConstant.PERCENT, 2, BigDecimal.ROUND_HALF_UP).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
//                        dimensionDto.setDimensionMatrixScore(matrixScore);
//                        reportExamStudentDto.setScore(reportExamStudentDto.getScore() + matrixScore);
//                        dimensionDtos.get(i).setDimensionMatrixScore(dimensionDtos.get(i).getDimensionMatrixScore() + matrixScore);
//                        dimensionMatrixSumScore = dimensionMatrixSumScore.add(new BigDecimal(matrixScore)).setScale(2, BigDecimal.ROUND_HALF_UP);
//                    }
//                    reportExamStudentFinalScoreDto.setTargetDimensionMatrixSumScore(dimensionMatrixSumScore.doubleValue());
//                    reportExamStudentFinalScoreAvgDto.setTargetDimensionMatrixSumScore(new BigDecimal(reportExamStudentFinalScoreAvgDto.getTargetDimensionMatrixSumScore()).add(dimensionMatrixSumScore).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
//                    ReportExamStudentUsualScoreDto reportExamStudentUsualScoreAvgDto = reportExamStudentTargetDto.getUsualScore();
//
//                    //平时作业总和+累加
//                    List<ReportExamStudentUsualScoreObjDto> reportExamStudentUsualScoreObjDtoList = reportExamStudentUsualScoreDto.getScoreList();
//                    List<ReportExamStudentUsualScoreObjDto> reportExamStudentUsualScoreObjAvgDtoList = reportExamStudentUsualScoreAvgDto.getScoreList();
//                    for (int i = 0; i < reportExamStudentUsualScoreObjDtoList.size(); i++) {
//                        ReportExamStudentUsualScoreObjDto reportExamStudentUsualScoreObjDto = reportExamStudentUsualScoreObjDtoList.get(i);
//                        reportExamStudentDto.setScore(reportExamStudentDto.getScore() + reportExamStudentUsualScoreObjDto.getMatrixScore());
//                        reportExamStudentUsualScoreObjAvgDtoList.get(i).setMatrixScore(new BigDecimal(reportExamStudentUsualScoreObjAvgDtoList.get(i).getMatrixScore()).add(new BigDecimal(reportExamStudentUsualScoreObjDto.getMatrixScore())).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
//                    }
//                    reportExamStudentTargetDtoMap.put(k, reportExamStudentTargetDto);
//                }
//                targetList.add(new ReportExamStudentTargetDto(courseTargetWordDto, reportExamStudentFinalScoreDto, reportExamStudentUsualScoreDto));
//            }
//            reportExamStudentDto.setTargetList(targetList);
//        });
//    }

//    /**
//     * 处理目标分&平均分&各课程目标平均分参数-知识点纬度
//     *
//     * @param reportExamStudentTargetDtoMap
//     * @param size
//     * @return
//     */
//    protected List<ReportExamStudentTargetDto> targetDimensionDtoParams(Map<Long, ReportExamStudentTargetDto> reportExamStudentTargetDtoMap, BigDecimal size) {
//        List<ReportExamStudentTargetDto> targetDtoList = new ArrayList<>();
//        reportExamStudentTargetDtoMap.forEach((k, v) -> {
//            ReportExamStudentFinalScoreDto reportExamStudentFinalScoreDto = v.getFinalScore();//课程目标考核要素的平均分
//            BigDecimal matrixAvgScore = new BigDecimal(reportExamStudentFinalScoreDto.getTargetDimensionMatrixSumScore()).divide(size, 2, BigDecimal.ROUND_HALF_UP).setScale(2, BigDecimal.ROUND_HALF_UP);
////            //如果换算出来的知识点总分超过了期末考试目标分，则
////            if (reportExamStudentFinalScoreDto.getTargetScore().compareTo(matrixAvgScore) == -1) {
////                throw ExceptionResultEnum.ERROR.exception("[" + v.getTargetName() + "]知识点总平均分超过了期末考试目标分，请重新设置知识点");
////            }
//            reportExamStudentFinalScoreDto.setMatrixAvgScore(matrixAvgScore.doubleValue());
//
//            List<DimensionDto> dimensionDtoList = reportExamStudentFinalScoreDto.getDimensionList();
//            for (DimensionDto d : dimensionDtoList) {
//                d.setDimensionMatrixAvgScore(new BigDecimal(d.getDimensionMatrixScore()).divide(size, 2, BigDecimal.ROUND_HALF_UP).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
//            }
//
//            v.setTargetMatrixAvgScore(reportExamStudentFinalScoreDto.getMatrixAvgScore());
//            ReportExamStudentUsualScoreDto reportExamStudentUsualScoreDto = v.getUsualScore();
//            List<ReportExamStudentUsualScoreObjDto> reportExamStudentUsualScoreObjDtoList = reportExamStudentUsualScoreDto.getScoreList();
//            for (ReportExamStudentUsualScoreObjDto r : reportExamStudentUsualScoreObjDtoList) {
//                r.setMatrixAvgScore(new BigDecimal(r.getMatrixScore()).divide(size, 2, BigDecimal.ROUND_HALF_UP).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
//                v.setTargetMatrixAvgScore(v.getTargetMatrixAvgScore() + r.getMatrixAvgScore());
//            }
//            v.setTargetMatrixAvgScore(new BigDecimal(v.getTargetMatrixAvgScore()).setScale(1, BigDecimal.ROUND_DOWN).doubleValue());
//            targetDtoList.add(v);
//        });
//        Collections.sort(targetDtoList);
//        return targetDtoList;
//    }

    /**
     * 处理目标分&平均分&各课程目标平均分参数-课程目标纬度
     *
     * @param reportExamStudentTargetDtoMap
     * @param size
     * @return
     */
    protected List<ReportExamStudentTargetDto> targetDtoParams(Map<Long, ReportExamStudentTargetDto> reportExamStudentTargetDtoMap, BigDecimal size) {
        List<ReportExamStudentTargetDto> targetDtoList = new ArrayList<>();
        reportExamStudentTargetDtoMap.forEach((k, v) -> {
            ReportExamStudentFinalScoreDto reportExamStudentFinalScoreDto = v.getFinalScore();//课程目标考核要素的平均分
            if (Objects.nonNull(reportExamStudentFinalScoreDto)) {
                BigDecimal matrixAvgScore = new BigDecimal(reportExamStudentFinalScoreDto.getTargetMatrixSumScore()).divide(size, 2, BigDecimal.ROUND_HALF_UP).setScale(2, BigDecimal.ROUND_HALF_UP);
                reportExamStudentFinalScoreDto.setMatrixAvgScore(matrixAvgScore.doubleValue());

                v.setTargetMatrixAvgScore(reportExamStudentFinalScoreDto.getMatrixAvgScore());
            }
            ReportExamStudentUsualScoreDto reportExamStudentUsualScoreDto = v.getUsualScore();
            List<ReportExamStudentUsualScoreObjDto> reportExamStudentUsualScoreObjDtoList = reportExamStudentUsualScoreDto.getScoreList();
            for (ReportExamStudentUsualScoreObjDto r : reportExamStudentUsualScoreObjDtoList) {
                r.setMatrixAvgScore(new BigDecimal(r.getMatrixScore()).divide(size, 2, BigDecimal.ROUND_HALF_UP).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
                v.setTargetMatrixAvgScore(Objects.nonNull(v.getTargetMatrixAvgScore()) ? v.getTargetMatrixAvgScore() : 0.0d + r.getMatrixAvgScore());
            }
            v.setTargetMatrixAvgScore(new BigDecimal(v.getTargetMatrixAvgScore()).setScale(1, BigDecimal.ROUND_DOWN).doubleValue());
            targetDtoList.add(v);
        });
        Collections.sort(targetDtoList);
        return targetDtoList;
    }
}
