package com.xinyilu.system.service.checkreport.impl;

import com.xinyilu.common.constant.Constants;
import com.xinyilu.common.utils.AgeUtil;
import com.xinyilu.system.domain.vo.TestItemStudentScore.AllClassByVO;
import com.xinyilu.system.domain.vo.TestItemStudentScore.AllStudentScoreVO;
import com.xinyilu.system.domain.vo.TestItemStudentScore.TestAllStudentScoreVO;
import com.xinyilu.system.domain.vo.TestItemStudentScore.TestAllStudentScoresVO;
import com.xinyilu.system.domain.vo.kindergartenSideAnalysis.KindergartenSideAnalysisVO;
import com.xinyilu.system.mapper.testItemScoreinfo.TestItemScoreMapper;
import com.xinyilu.system.service.checkreport.KindergartenSideAnalysisTestAllStudentScoreService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;
import java.util.Objects;

/**
 * @author ljh
 * @version 1.0
 * Create by 2022/9/29 12:51
 */
@Service
@Slf4j
public class KindergartenSideAnalysisTestAllStudentScoreServiceImpl implements KindergartenSideAnalysisTestAllStudentScoreService {

    @Resource
    private TestItemScoreMapper testItemScoreMapper;


    /**
     * 三岁年龄值
     */
    private static final double THREE_AGE = 3;
    /**
     * 四岁年龄值
     */
    private static final double FOUR_AGE = 4;
    /**
     * 五岁年龄值
     */
    private static final double FIVE_AGE = 5;

    /**
     * 六岁年龄值
     */
    private static final double SIX_AGE = 6;

    /**
     * 六十分标识
     */
    private static final BigDecimal SIXTY_SCORE = BigDecimal.valueOf(60);

    /**
     * 八十分标识
     */
    private static final BigDecimal EIGHTY_SCORE = BigDecimal.valueOf(80);

    /**
     * 体侧达标分析
     *
     * @param sideAnalysisList 体侧信息
     * @param batchCode        批次code
     * @return com.xinyilu.system.domain.vo.kindergartenSideAnalysis.KindergartenSideAnalysisVO
     **/
    @Override
    public KindergartenSideAnalysisVO getKindergartenSideAnalysis(List<KindergartenSideAnalysisVO> sideAnalysisList, String batchCode) throws Exception {
        KindergartenSideAnalysisVO sideAnalysisVO = new KindergartenSideAnalysisVO();
        sideAnalysisVO.setBatchCode(batchCode);
        //幼儿园信息
        if (CollectionUtils.isEmpty(sideAnalysisList)) {
            return null;
        }
        sideAnalysisVO.setKindergartenName(StringUtils.isBlank(sideAnalysisList.get(0).getKindergartenName()) ? "" : sideAnalysisList.get(0).getKindergartenName());
        sideAnalysisVO.setKindergartenType(StringUtils.isBlank(sideAnalysisList.get(0).getKindergartenType()) ? "" : sideAnalysisList.get(0).getKindergartenType());
        int totalCount = sideAnalysisList.size();
        sideAnalysisVO.setTestItemStudentCount(totalCount);
        //计算学生的年龄
        for (KindergartenSideAnalysisVO analysisVO : sideAnalysisList) {
            analysisVO.setStudentAge(AgeUtil.getStudentAgeMonth(Objects.isNull(analysisVO.getBirthDate()) ? LocalDate.now().toString() : analysisVO.getBirthDate().toString()));
        }
        //计算年龄为三岁和四岁的男性学生的人数
        double threeAndFourMaleCount = getStudentAgeCount(sideAnalysisList, Constants.MALE, THREE_AGE, FOUR_AGE);
        sideAnalysisVO.setThreeAndFourMaleCount(threeAndFourMaleCount);
        //计算年龄为三岁和四岁的女性学生的人数
        double threeAndFourFeMaleCount = getStudentAgeCount(sideAnalysisList, Constants.FEMALE, THREE_AGE, FOUR_AGE);
        sideAnalysisVO.setThreeAndFourFeMaleCount(threeAndFourFeMaleCount);
        //计算年龄为四岁和五岁的男性学生的人数
        double fourAndFiveMaleCount = getStudentAgeCount(sideAnalysisList, Constants.MALE, FOUR_AGE, FIVE_AGE);
        sideAnalysisVO.setFourAndFiveMaleCount(fourAndFiveMaleCount);
        //计算年龄为四岁和五岁的女性学生的人数
        double fourAndFiveFeMaleCount = getStudentAgeCount(sideAnalysisList, Constants.FEMALE, FOUR_AGE, FIVE_AGE);
        sideAnalysisVO.setFourAndFiveFeMaleCount(fourAndFiveFeMaleCount);
        //计算年龄为五岁和六岁的男性学生的人数
        double fiveAndSixMaleCount = getStudentAgeCount(sideAnalysisList, Constants.MALE, FIVE_AGE, SIX_AGE);
        sideAnalysisVO.setFiveAndSixMaleCount(fiveAndSixMaleCount);
        //计算年龄为五岁和六岁的女性学生的人数
        double fiveAndSixFeMaleCount = getStudentAgeCount(sideAnalysisList, Constants.FEMALE, FIVE_AGE, SIX_AGE);
        sideAnalysisVO.setFiveAndSixFeMaleCount(fiveAndSixFeMaleCount);
        //计算年龄为六岁以上的男性学生的人数
        double sixAndMoreMaleCount = getGreaterThanStudentAgeCount(sideAnalysisList, Constants.MALE);
        sideAnalysisVO.setSixAndMoreMaleCount(sixAndMoreMaleCount);
        //计算六岁以上的女性学生的人数
        double sixAndMoreFeMaleCount = getGreaterThanStudentAgeCount(sideAnalysisList, Constants.FEMALE);
        sideAnalysisVO.setSixAndMoreFeMaleCount(sixAndMoreFeMaleCount);
        //找出成绩小于六十分的人数
        long sixtyScoreCount = sideAnalysisList.stream().filter(score -> Objects.nonNull(score.getItemScore()))
                .filter(score -> score.getItemScore().compareTo(SIXTY_SCORE) < 0).count();
        //找出成绩在六十分到八十分之间的人数
        long sixtyAndEightyScoreCount = sideAnalysisList.stream().filter(score -> Objects.nonNull(score.getItemScore()))
                .filter(score -> score.getItemScore().compareTo(SIXTY_SCORE) >= 0 && score.getItemScore().compareTo(EIGHTY_SCORE) <= 0).count();
        //找出成绩在八十分以上的人数
        long eightyScoreCount = sideAnalysisList.stream().filter(score -> Objects.nonNull(score.getItemScore()))
                .filter(score -> score.getItemScore().compareTo(EIGHTY_SCORE) > 0).count();
        //不合格率
        if (sixtyScoreCount != 0 && totalCount != 0) {
            sideAnalysisVO.setUnQualifyRate(BigDecimal.valueOf(sixtyScoreCount).divide(BigDecimal.valueOf(totalCount), 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100).setScale(2, BigDecimal.ROUND_HALF_UP)));
        } else {
            sideAnalysisVO.setUnQualifyRate(BigDecimal.ZERO);
        }
        //合格率
        if (sixtyAndEightyScoreCount != 0 && totalCount != 0) {
            sideAnalysisVO.setQualifyRate(BigDecimal.valueOf(sixtyAndEightyScoreCount).divide(BigDecimal.valueOf(totalCount), 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100).setScale(2, BigDecimal.ROUND_HALF_UP)));
        } else {
            sideAnalysisVO.setQualifyRate(BigDecimal.ZERO);
        }
        //优秀率
        if (eightyScoreCount != 0 && totalCount != 0) {
            sideAnalysisVO.setExcellentRate(BigDecimal.valueOf(eightyScoreCount).divide(BigDecimal.valueOf(totalCount), 2, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(2, BigDecimal.ROUND_HALF_UP));
        } else {
            sideAnalysisVO.setExcellentRate(BigDecimal.ZERO);
        }
        //达标率
        BigDecimal qualifyRate = Objects.isNull(sideAnalysisVO.getQualifyRate()) ? BigDecimal.ZERO : sideAnalysisVO.getQualifyRate();
        BigDecimal excellentRate = Objects.isNull(sideAnalysisVO.getExcellentRate()) ? BigDecimal.ZERO : sideAnalysisVO.getExcellentRate();
        sideAnalysisVO.setStandardRate(qualifyRate.add(excellentRate).setScale(2, BigDecimal.ROUND_HALF_UP));
        return sideAnalysisVO;
    }


    /**
     * 计算不同年龄段的学生的数量
     *
     * @param sideAnalysisList 学生信息集合
     * @param startYear        开始年龄
     * @param endYear          结束年龄
     * @param studentSex       学生性别
     * @return 学生数量
     */
    private double getStudentAgeCount(List<KindergartenSideAnalysisVO> sideAnalysisList, String studentSex,
                                      double startYear, double endYear) {
        return sideAnalysisList.stream()
                .filter(item -> Objects.nonNull(item.getStudentAge()) && StringUtils.isNotBlank(item.getStudentSex()))
                .filter(item -> studentSex.equals(item.getStudentSex()))
                .filter(item -> item.getStudentAge() >= startYear && item.getStudentAge() < endYear).count();
    }


    /**
     * 计算大于年龄段的学生的数量
     *
     * @param sideAnalysisList 学生信息集合
     * @param studentSex       学生性别
     * @return 学生数量
     */
    private double getGreaterThanStudentAgeCount(List<KindergartenSideAnalysisVO> sideAnalysisList,
                                                 String studentSex) {
        return sideAnalysisList.stream()
                .filter(item -> Objects.nonNull(item.getStudentAge()) && StringUtils.isNotBlank(item.getStudentSex()))
                .filter(item -> studentSex.equals(item.getStudentSex()))
                .filter(item -> item.getStudentAge() >= KindergartenSideAnalysisTestAllStudentScoreServiceImpl.SIX_AGE).count();
    }


    /**
     * 体测概况分析
     *
     * @param kindergartenId 幼儿园id
     * @param batchCode      批次编号
     * @return com.xinyilu.system.domain.vo.TestItemStudentScore.TestAllStudentScoresVO
     **/
    @Override
    public TestAllStudentScoresVO selectAllStudentScoreList(@Param("kindergartenId") Long kindergartenId, @Param("batchCode") String batchCode) {
        TestAllStudentScoresVO testAllStudentScoresVO = new TestAllStudentScoresVO();
        // 全园优秀幼儿排行
        List<TestAllStudentScoreVO> testAllStudentScoreList = testItemScoreMapper.selectAllStudentScoreList(kindergartenId, batchCode);
        //班级综合体测成绩排名
        List<AllStudentScoreVO> allStudentScoreList = testItemScoreMapper.selectAllClassScoreList(kindergartenId, batchCode);
        //班级优秀幼儿榜
        List<AllClassByVO> allClassById = testItemScoreMapper.selectAllClassById(kindergartenId, batchCode);
        if (CollectionUtils.isEmpty(testAllStudentScoreList) && CollectionUtils.isEmpty(allStudentScoreList) && CollectionUtils.isEmpty(allClassById)) {
            return testAllStudentScoresVO;
        }
        // 把数据放入到bean中   全园优秀幼儿排行
        testAllStudentScoresVO.setTestAllStudentScoreVOList(testAllStudentScoreList);
        // 把数据放入到bean中  班级综合体测成绩排名
        testAllStudentScoresVO.setAllStudentScoreVOList(allStudentScoreList);
        // 把数据放入到bean中   班级综合体测成绩排名
        testAllStudentScoresVO.setAllClassByVOList(allClassById);
        return testAllStudentScoresVO;
    }

}
