package com.xiaoniu.subsystem.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xiaoniu.common.core.utils.BeanUtil;
import com.xiaoniu.common.core.utils.DateUtils;
import com.xiaoniu.common.core.utils.StringUtils;
import com.xiaoniu.common.core.vo.AnalysisLineVO;
import com.xiaoniu.common.core.vo.LabelAndValueNameVO;
import com.xiaoniu.common.core.vo.LabelAndValueVO;
import com.xiaoniu.common.security.utils.SecurityUtils;
import com.xiaoniu.subsystem.business.domain.*;
import com.xiaoniu.subsystem.business.domain.dto.ExpenseStatisticsDTO;
import com.xiaoniu.subsystem.business.domain.vo.*;
import com.xiaoniu.subsystem.business.mapper.*;
import com.xiaoniu.subsystem.business.service.IStatisticalAnalysisService;
import com.xiaoniu.subsystem.system.domain.SysDictData;
import com.xiaoniu.subsystem.system.domain.Unit;
import com.xiaoniu.subsystem.system.mapper.SysDictDataMapper;
import com.xiaoniu.subsystem.system.mapper.UnitMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Year;
import java.util.*;
import java.util.stream.Collectors;

import static com.xiaoniu.common.security.utils.SecurityUtils.getUnitId;

/**
 * @Author haoxuyang
 * @Date 2024/11/29 14:27
 */
@Service
public class StatisticalAnalysisServiceImpl implements IStatisticalAnalysisService {
    @Resource
    private ProjectPersonnelInfoMapper projectPersonnelInfoMapper;
    @Resource
    private ProjectMapper projectMapper;
    @Resource
    private UnitMapper unitMapper;
    @Resource
    private ExpenseMapper expenseMapper;
    @Resource
    private FlightMapper flightMapper;
    @Resource
    private DemandMapper demandMapper;

    @Resource
    private StudentInfoMapper studentInfoMapper;
    @Resource
    private GraduationAssessmentMapper graduationAssessmentMapper;

    @Resource
    private SysDictDataMapper dictDataMapper;

    public static void main(String[] args) {
        BigDecimal num1 = new BigDecimal(0);
        BigDecimal num2 = new BigDecimal(6);
        BigDecimal num3 = null;
        num3 = num1.add(num2);
        System.out.println(num3);

    }

    @Override
    public AnalysisLineVO excellentStudent() {
        AnalysisLineVO analysisLineVO = new AnalysisLineVO();
        List<AnalysisLineVO.DataList> dataList = new ArrayList<>();
        AnalysisLineVO.DataList list = new AnalysisLineVO.DataList();
        list.setName("历年优秀学员统计");
        list.setType("column");
        list.setYAxisData(new ArrayList<>());
        List<String> xAxisData = new ArrayList<>();
        // 获取当前年份
        List<String> yearList = DateUtils.getYearCollectionExample(6);
/*        Long unitId = getUnitId();
        if (StringUtils.isNull(unitId)) {
            return analysisLineVO;
        }
        //获取子级部门id
        List<Long> unitIdList = unitMapper.juniorUnit(unitId);

        //计算历年优秀学员数量
        List<LabelAndValueVO> excellentStudentList = projectPersonnelInfoMapper.getExcellentStudent(yearList, unitIdList);
        Map<String, String> map = new HashMap<>();
        if (!CollectionUtils.isEmpty(excellentStudentList)) {
            map = excellentStudentList.stream().collect(Collectors.toMap(LabelAndValueVO::getValue, LabelAndValueVO::getLabel));
        }*/

        List<StudentInfo> studentInfos = studentInfoMapper.selectList(new LambdaQueryWrapper<StudentInfo>()
                .in(StudentInfo::getYear, yearList)
                .eq(StudentInfo::getCreateDept, getUnitId())
        );
        Map<String, List<StudentInfo>> infoMap = studentInfos.stream().collect(Collectors.groupingBy(StudentInfo::getYear));
        Map<String, String> map = new HashMap<>();
        infoMap.keySet().forEach(k -> {
            List<StudentInfoVO> infoVOs = new ArrayList<>();
            // 匹配考评等级和培训结束时间
            for (StudentInfo studentInfo : infoMap.get(k)) {
                StudentInfoVO studentInfoVO = BeanUtil.copy(studentInfo, StudentInfoVO.class);
                // 匹配结束时间
                Date trainingTime = studentInfo.getTrainingTime();
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(trainingTime);
                calendar.add(Calendar.DATE, Integer.valueOf(studentInfo.getEducationalSystem()));
                studentInfoVO.setEndTime(calendar.getTime());
                // 匹配等级
                String idCard = studentInfo.getIdCard();
                Long flightId = studentInfo.getFlightId();
                GraduationAssessment graduationAssessment = graduationAssessmentMapper.getGraduationAssessmentByFlightIdAndIdCard(flightId, idCard);
                if (graduationAssessment != null) {
                    studentInfoVO.setEvaluationOrder(graduationAssessment.getEvaluationOrder());
                    infoVOs.add(studentInfoVO);
                }
            }
            if (com.alibaba.nacos.common.utils.CollectionUtils.isNotEmpty(infoVOs)) {
                int count = (int) infoVOs.stream().filter(
                        l -> StringUtils.equals("0", l.getEvaluationOrder())).count();
                map.put(k, String.valueOf(count));
            }

        });


        for (String year : yearList) {
            xAxisData.add(year);
            if (!CollectionUtils.isEmpty(map)) {
                list.getYAxisData().add(StringUtils.isNotEmpty(map.get(year)) ? map.get(year) : "0");
            } else {
                list.getYAxisData().add("0");
            }
        }
        dataList.add(list);
        analysisLineVO.setXAxisData(xAxisData);
        analysisLineVO.setDataList(dataList);
        return analysisLineVO;
    }

    @Override
    public NumberParticipantsVO numberParticipants() {
/*        NumberParticipantsVO numberParticipantsVO = new NumberParticipantsVO();
        Long unitId = getUnitId();
        if (StringUtils.isNull(unitId)) {
            return numberParticipantsVO;
        }
        //获取子级部门id
        List<Long> unitIdList = unitMapper.juniorUnit(unitId);
        unitIdList.remove(unitId);
        //获取当前年份
        List<String> yearList = DateUtils.getYearCollectionExample(6);
        //获取计划参训人数
        Integer planParticipate = projectMapper.getPlanParticipateNum(unitIdList, yearList, null);
        numberParticipantsVO.setPlanParticipate(planParticipate);
        //获取实际参训人数
        Integer actualParticipate = projectPersonnelInfoMapper.getActualParticipateNum(unitIdList, yearList, null);
        numberParticipantsVO.setActualParticipate(actualParticipate);

        AnalysisLineVO analysisLineVO = new AnalysisLineVO();
        List<AnalysisLineVO.DataList> dataList = new ArrayList<>();
        List<String> xAxisData = new ArrayList<>();


        List<ParticipantsVO> participantsList = projectPersonnelInfoMapper.getNumberParticipants(yearList, unitIdList);
        if (CollectionUtils.isEmpty(participantsList)) {
            return numberParticipantsVO;
        }

        Map<Long, List<ParticipantsVO>> map = participantsList.stream().collect(Collectors.groupingBy(ParticipantsVO::getSendingUnitId));
        for (Map.Entry<Long, List<ParticipantsVO>> entry : map.entrySet()) {
            List<ParticipantsVO> sendingUnitList = entry.getValue();
            AnalysisLineVO.DataList list = new AnalysisLineVO.DataList();
            list.setName(StringUtils.isNotNull(sendingUnitList.get(0).getSendingUnitName()) ? sendingUnitList.get(0).getSendingUnitName() : "");
            list.setType("column");
            list.setYAxisData(new ArrayList<>());
            Map<String, List<ParticipantsVO>> listMap = sendingUnitList.stream().collect(Collectors.groupingBy(ParticipantsVO::getYear));
            for (String year : yearList) {
                xAxisData.add(year);
                List<ParticipantsVO> participantsVOList = listMap.get(year);
                if (!CollectionUtils.isEmpty(participantsVOList)) {
                    list.getYAxisData().add(String.valueOf(participantsVOList.stream().map(l ->
                                    BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(l.getNum()) ?
                                            "0" : l.getNum())))
                            .reduce(BigDecimal.ZERO, BigDecimal::add)));
                } else {
                    list.getYAxisData().add("0");
                }
            }
            dataList.add(list);
        }
        analysisLineVO.setDataList(dataList);
        analysisLineVO.setXAxisData(xAxisData.stream().distinct().collect(Collectors.toList()));
        numberParticipantsVO.setAnalysisLineVO(analysisLineVO);*/

        NumberParticipantsVO numberParticipantsVO = new NumberParticipantsVO();
        // 获取当前年份
        List<String> yearList = DateUtils.getYearCollectionExample(6);
        AnalysisLineVO analysisLineVO = new AnalysisLineVO();
        List<AnalysisLineVO.DataList> list = new ArrayList<>();


        List<StudentInfo> studentInfos = studentInfoMapper.selectList(new LambdaQueryWrapper<StudentInfo>()
                .in(StudentInfo::getYear, yearList)
                .eq(StudentInfo::getCreateDept, getUnitId())
        );
        // 实际参训人数
        numberParticipantsVO.setActualParticipate(studentInfos.size());
        Map<String, List<StudentInfo>> infoMap = studentInfos.stream().collect(Collectors.groupingBy(StudentInfo::getMainUnitName));
        infoMap.keySet().forEach(k -> {
            AnalysisLineVO.DataList dataList = new AnalysisLineVO.DataList();
            dataList.setName(k);
            dataList.setType("column");
            dataList.setYAxisData(new ArrayList<>());
            List<StudentInfo> unitInfos = infoMap.get(k);
            for (String year : yearList) {
                long count = unitInfos.stream().filter(s -> s.getYear().equals(year)).count();
                dataList.getYAxisData().add(String.valueOf(count));
            }
            list.add(dataList);
        });
        analysisLineVO.setXAxisData(yearList);
        analysisLineVO.setDataList(list);
        numberParticipantsVO.setAnalysisLineVO(analysisLineVO);

        return numberParticipantsVO;
    }

    @Override
    public AnalysisLineVO overYearsParticipants() {
        AnalysisLineVO analysisLineVO = new AnalysisLineVO();
        List<AnalysisLineVO.DataList> dataList = new ArrayList<>();

        /*Long unitId = getUnitId();
        if (StringUtils.isNull(unitId)) {
            return analysisLineVO;
        }
        //获取子级部门id
        List<Long> unitIdList = unitMapper.juniorUnit(unitId);
        //获取当前年份
        List<String> yearList = DateUtils.getYearCollectionExample(6);
        //获取实际参训人员
        List<LabelAndValueVO> projectPersonnelList = projectPersonnelInfoMapper.overYearsParticipants(unitIdList, yearList);
        Map<String, String> projectPersonnelMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(projectPersonnelList)) {
            projectPersonnelMap = projectPersonnelList.stream().collect(Collectors.toMap(LabelAndValueVO::getValue, LabelAndValueVO::getLabel));
        }
        //获取计划参训人员
        List<LabelAndValueVO> projectList = projectMapper.overYearsParticipants(unitIdList, yearList);
        Map<String, String> projectMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(projectList)) {
            projectMap = projectList.stream().collect(Collectors.toMap(LabelAndValueVO::getValue, LabelAndValueVO::getLabel));
        }
        List<String> yearList = DateUtils.getYearCollectionExample(6);
        AnalysisLineVO.DataList list1 = new AnalysisLineVO.DataList();
        list1.setName("实际");
        list1.setType("line");
        list1.setYAxisData(new ArrayList<>());
        AnalysisLineVO.DataList list2 = new AnalysisLineVO.DataList();
        list2.setName("计划");
        list2.setType("line");
        list2.setYAxisData(new ArrayList<>());
        List<String> xAxisData = new ArrayList<>();*/

        List<String> yearList = DateUtils.getYearCollectionExample(6);
        AnalysisLineVO.DataList list1 = new AnalysisLineVO.DataList();
        list1.setName("实际");
        list1.setType("line");
        list1.setYAxisData(new ArrayList<>());
        List<String> xAxisData = new ArrayList<>();

        List<StudentInfo> studentInfos = studentInfoMapper.selectList(new LambdaQueryWrapper<StudentInfo>()
                .in(StudentInfo::getYear, yearList)
                .eq(StudentInfo::getCreateDept, getUnitId())
        );
        Map<String, List<StudentInfo>> infoMap = studentInfos.stream().collect(Collectors.groupingBy(StudentInfo::getYear));
        Map<String, String> map = new HashMap<>();
        infoMap.keySet().forEach(k -> {
            if (com.alibaba.nacos.common.utils.CollectionUtils.isNotEmpty(infoMap.get(k))) {
                int count = com.alibaba.nacos.common.utils.CollectionUtils.isNotEmpty(infoMap.get(k)) ? infoMap.get(k).size() : 0;
                map.put(k, String.valueOf(count));
            }

        });


        for (String year : yearList) {
            xAxisData.add(year);
            if (!CollectionUtils.isEmpty(map)) {
                list1.getYAxisData().add(StringUtils.isNotEmpty(map.get(year)) ? map.get(year) : "0");
            } else {
                list1.getYAxisData().add("0");
            }
/*            if (!CollectionUtils.isEmpty(projectMap)) {
                list2.getYAxisData().add(StringUtils.isNotEmpty(projectMap.get(year)) ? projectMap.get(year) : "0");
            } else {
                list2.getYAxisData().add("0");
            }*/
        }
        dataList.add(list1);
        // dataList.add(list2);
        analysisLineVO.setXAxisData(xAxisData);
        analysisLineVO.setDataList(dataList);
        return analysisLineVO;
    }

    @Override
    public List<LabelAndValueVO> trainingType() {
        /*Long unitId = getUnitId();
        if (StringUtils.isNull(unitId)) {
            return new ArrayList<>();
        }
        //获取子级部门id
        List<Long> unitIdList = unitMapper.juniorUnit(unitId);
        return projectPersonnelInfoMapper.trainingType(unitIdList);*/

        List<LabelAndValueVO> list = new ArrayList<>();
        Map<String, String> map = new HashMap<>();
        List<StudentInfo> studentInfos = studentInfoMapper.selectList(new LambdaQueryWrapper<StudentInfo>()
                .eq(StudentInfo::getCreateDept, getUnitId()));

        List<SysDictData> data = dictDataMapper.selectList(
                new LambdaQueryWrapper<SysDictData>()
                        .eq(SysDictData::getDictType, "1")
                        .orderByDesc(SysDictData::getDictLabel));
        Map<String, String> labelMap = data.stream()
                .collect(Collectors.toMap(SysDictData::getDictLabel, SysDictData::getDictValue));
        if (CollectionUtils.isEmpty(studentInfos)){
            for (SysDictData datum : data) {
                LabelAndValueVO vo = new LabelAndValueVO();
                vo.setLabel(datum.getDictValue());
                vo.setValue("0");
                list.add(vo);
            }
            return list;
        }
        Map<String, List<StudentInfo>> infoMap = studentInfos.stream().collect(Collectors.groupingBy(StudentInfo::getMajorType));
        infoMap.keySet().forEach(k -> {
            if (!CollectionUtils.isEmpty(infoMap.get(k))) {
                int count = !CollectionUtils.isEmpty(infoMap.get(k)) ? infoMap.get(k).size() : 0;
                map.put(k, String.valueOf(count));
            }
        });
        map.keySet().forEach(k -> {
            LabelAndValueVO vo = new LabelAndValueVO();
            vo.setLabel(labelMap.get(k));
            vo.setValue(map.get(k));
            list.add(vo);
        });
        return list;
    }

    @Override
    public AnalysisLineVO comparisonGrades() {
        AnalysisLineVO analysisLineVO = new AnalysisLineVO();
        List<AnalysisLineVO.DataList> dataList = new ArrayList<>();
        AnalysisLineVO.DataList list1 = new AnalysisLineVO.DataList();
        list1.setName("入学摸底考试成绩");
        list1.setType("line");
        list1.setYAxisData(new ArrayList<>());
        AnalysisLineVO.DataList list2 = new AnalysisLineVO.DataList();
        list2.setName("结业考核成绩");
        list2.setType("line");
        list2.setYAxisData(new ArrayList<>());
        List<String> xAxisData = new ArrayList<>();
        // 获取当前年份
        List<String> yearList = DateUtils.getYearCollectionExample(6);
/*        Long unitId = getUnitId();
        if (StringUtils.isNull(unitId)) {
            return analysisLineVO;
        }
        //获取子级部门id
        List<Long> unitIdList = unitMapper.juniorUnit(unitId);
//        List<Long> unitIdList= Arrays.asList(1L,2L,3L);

        List<ComparisonGradesVO> comparisonGradesList = projectPersonnelInfoMapper.comparisonGrades(unitIdList);
        List<ComparisonGradesVO> placementTest = comparisonGradesList.stream().filter(o -> o.getType().equals("placement_test")).toList();
        List<ComparisonGradesVO> finalTest = comparisonGradesList.stream().filter(o -> o.getType().equals("final_test")).toList();*/


        List<ComparisonGradesVO> placementTest = new ArrayList<>();
        List<ComparisonGradesVO> finalTest = new ArrayList<>();

        List<StudentInfo> studentInfos = studentInfoMapper.selectList(new LambdaQueryWrapper<StudentInfo>()
                .in(StudentInfo::getYear, yearList)
                .eq(StudentInfo::getCreateDept, getUnitId())
        );
        Map<String, List<StudentInfo>> infoMap = studentInfos.stream().collect(Collectors.groupingBy(StudentInfo::getYear));
        infoMap.keySet().forEach(k -> {
            List<StudentInfoVO> infoVOs = new ArrayList<>();
            List<StudentInfoVO> infoVO2s = new ArrayList<>();
            // 匹配考评等级和培训结束时间
            for (StudentInfo studentInfo : infoMap.get(k)) {
                StudentInfoVO studentInfoVO = BeanUtil.copy(studentInfo, StudentInfoVO.class);
                // 匹配结束时间
                Date trainingTime = studentInfo.getTrainingTime();
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(trainingTime);
                calendar.add(Calendar.DATE, Integer.valueOf(studentInfo.getEducationalSystem()));
                studentInfoVO.setEndTime(calendar.getTime());
                // 匹配等级
                String idCard = studentInfo.getIdCard();
                Long flightId = studentInfo.getFlightId();
                GraduationAssessment graduationAssessment = graduationAssessmentMapper.getGraduationAssessmentByFlightIdAndIdCard(flightId, idCard);
                if (graduationAssessment != null) {
                    if (graduationAssessment.getTotalScore() != null) {
                        studentInfoVO.setEvaluationOrder(graduationAssessment.getEvaluationOrder());
                        studentInfoVO.setTotalScore(graduationAssessment.getTotalScore());

                        infoVOs.add(studentInfoVO);
                    }
                    if (graduationAssessment.getAdmissionScore() != null) {
                        studentInfoVO.setAdmissionScore(graduationAssessment.getAdmissionScore());
                        infoVO2s.add(studentInfoVO);
                    }
                }
            }

            ComparisonGradesVO comparisonGradesVO1 = new ComparisonGradesVO();
            comparisonGradesVO1.setYear(k);
            comparisonGradesVO1.setTestNum(BigDecimal.valueOf(infoVOs.size()));
            BigDecimal test = new BigDecimal(0);

            for (StudentInfoVO stu : infoVOs) {
                BigDecimal total = new BigDecimal(stu.getTotalScore());
                test = test.add(total);
            }
            comparisonGradesVO1.setTest(test);
            if (comparisonGradesVO1.getTestNum().compareTo(BigDecimal.ZERO) == 0) {
                comparisonGradesVO1.setTestAve(BigDecimal.ZERO);
            }else {
                comparisonGradesVO1.setTestAve(comparisonGradesVO1.getTest().divide(comparisonGradesVO1.getTestNum(), 2, RoundingMode.HALF_UP));
            }
            finalTest.add(comparisonGradesVO1);


            ComparisonGradesVO comparisonGradesVO2 = new ComparisonGradesVO();
            comparisonGradesVO2.setYear(k);
            comparisonGradesVO2.setTestNum(BigDecimal.valueOf(infoVO2s.size()));
            BigDecimal test2 = BigDecimal.ZERO;

            for (StudentInfoVO stu : infoVO2s) {
                BigDecimal admissionScore = new BigDecimal(stu.getAdmissionScore());
                test2 = test2.add(admissionScore);
            }
            comparisonGradesVO2.setTest(test2);
            if (comparisonGradesVO1.getTestNum().compareTo(BigDecimal.ZERO) == 0) {
                comparisonGradesVO1.setTestAve(BigDecimal.ZERO);
            }else {
                comparisonGradesVO1.setTestAve(comparisonGradesVO1.getTest().divide(comparisonGradesVO1.getTestNum(), 2, RoundingMode.HALF_UP));
            }
            placementTest.add(comparisonGradesVO2);
        });


        Map<String, BigDecimal> placementMap = placementTest.stream().collect(Collectors.toMap(ComparisonGradesVO::getYear, ComparisonGradesVO::getTestAve));
        Map<String, BigDecimal> finalMap = finalTest.stream().collect(Collectors.toMap(ComparisonGradesVO::getYear, ComparisonGradesVO::getTestAve));
/*        Map<String, BigDecimal> placementMap = new HashMap<>();
        Map<String, BigDecimal> finalMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(placementTest)) {
            for (ComparisonGradesVO comparisonGradesVO : placementTest) {
                if (BigDecimal.ZERO.compareTo(comparisonGradesVO.getTest()) < 0) {
                    comparisonGradesVO.setTestAve(comparisonGradesVO.getTest().divide(comparisonGradesVO.getTestNum(), 2, RoundingMode.HALF_UP));
                }
            }
            placementMap = placementTest.stream().collect(Collectors.toMap(ComparisonGradesVO::getYear, ComparisonGradesVO::getTestAve));
        }
        if (!CollectionUtils.isEmpty(finalTest)) {
            for (ComparisonGradesVO comparisonGradesVO : finalTest) {
                if (BigDecimal.ZERO.compareTo(comparisonGradesVO.getTest()) < 0) {
                    comparisonGradesVO.setTestAve(comparisonGradesVO.getTest().divide(comparisonGradesVO.getTestNum(), 2, RoundingMode.HALF_UP));
                }
            }
            finalMap = finalTest.stream().collect(Collectors.toMap(ComparisonGradesVO::getYear, ComparisonGradesVO::getTestAve));
        }*/
        for (String year : yearList) {
            xAxisData.add(year);
            if (!CollectionUtils.isEmpty(placementMap)) {
                list1.getYAxisData().add(StringUtils.isNotNull(placementMap.get(year)) ? String.valueOf(placementMap.get(year)) : "0");
            } else {
                list1.getYAxisData().add("0");
            }
            if (!CollectionUtils.isEmpty(finalMap)) {
                list2.getYAxisData().add(StringUtils.isNotNull(finalMap.get(year)) ? String.valueOf(finalMap.get(year)) : "0");
            } else {
                list2.getYAxisData().add("0");
            }
        }
        dataList.add(list1);
        dataList.add(list2);
        analysisLineVO.setXAxisData(xAxisData);
        analysisLineVO.setDataList(dataList);
        return analysisLineVO;
    }

    @Override
    public List<LabelAndValueVO> scoreProportion() {
/*        List<LabelAndValueVO> valueVOList = new ArrayList<>();
        Long unitId = getUnitId();
        if (StringUtils.isNull(unitId)) {
            return valueVOList;
        }
        //获取子级部门id
        List<Long> unitIdList = unitMapper.juniorUnit(unitId);
        return projectPersonnelInfoMapper.scoreProportion(unitIdList);*/

        List<LabelAndValueVO> list = new ArrayList<>();
        List<StudentInfoVO> infoVOs = new ArrayList<>();
        List<StudentInfo> studentInfos = studentInfoMapper.selectList(new LambdaQueryWrapper<StudentInfo>()
                .eq(StudentInfo::getCreateDept, getUnitId())
        );
        for (StudentInfo studentInfo : studentInfos) {
            StudentInfoVO studentInfoVO = BeanUtil.copy(studentInfo, StudentInfoVO.class);
            // 匹配等级
            String idCard = studentInfo.getIdCard();
            Long flightId = studentInfo.getFlightId();
            GraduationAssessment graduationAssessment = graduationAssessmentMapper.getGraduationAssessmentByFlightIdAndIdCard(flightId, idCard);
            if (graduationAssessment != null) {
                studentInfoVO.setEvaluationOrder(graduationAssessment.getEvaluationOrder());
                infoVOs.add(studentInfoVO);
            }

        }
        int size = infoVOs.stream().filter(studentInfoVO -> StringUtils.isNotNull(studentInfoVO.getEvaluationOrder())).toList().size();
        if (size == 0) {
            return list;
        }
        Map<String, String> labelMap = new HashMap<>();
        // 优秀，1良好，2及格，3不及格
        labelMap.put("0", "优秀");
        labelMap.put("1", "良好");
        labelMap.put("2", "及格");
        labelMap.put("3", "不及格");
        Map<String, List<StudentInfoVO>> map = infoVOs.stream().collect(Collectors.groupingBy(StudentInfoVO::getEvaluationOrder));
        map.keySet().forEach(k -> {
            LabelAndValueVO vo = new LabelAndValueVO();
            vo.setLabel(labelMap.get(k));
            vo.setValue(String.valueOf(map.get(k).size()));
            list.add(vo);
        });
        return list;
    }

    @Override
    public List<LabelAndValueNameVO> expensePersonnel(ExpenseStatisticsDTO dto) {
        List<LabelAndValueNameVO> voList = new ArrayList<>();
        List<Expense> list = expenseMapper.selectList(new LambdaQueryWrapper<Expense>()
                .eq(null != dto.getFlightId(), Expense::getFlightId, dto.getFlightId())
                .eq(StringUtils.isBlank(dto.getYear()), Expense::getYear, Year.now().getValue())
                .eq(StringUtils.isNotBlank(dto.getYear()), Expense::getYear, dto.getYear()));
        if (CollectionUtils.isEmpty(list)) {
            voList.add(new LabelAndValueNameVO().setName("计划参训人数").setValue("0"));
            voList.add(new LabelAndValueNameVO().setName("实际参训人数").setValue("0"));
            return voList;
        }
        voList.add(new LabelAndValueNameVO()
                .setName("计划参训人数")
                .setValue(String.valueOf(list.stream().map(l ->
                                BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(l.getPlannedNumber()) ?
                                        "0" : l.getPlannedNumber())))
                        .reduce(BigDecimal.ZERO, BigDecimal::add))));
        voList.add(new LabelAndValueNameVO()
                .setName("实际参训人数")
                .setValue(String.valueOf(list.stream().map(l ->
                                BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(l.getParticipantsNumber()) ?
                                        "0" : l.getParticipantsNumber())))
                        .reduce(BigDecimal.ZERO, BigDecimal::add))));
        return voList;
    }

    @Override
    public AnalysisLineVO expenseAmount(ExpenseStatisticsDTO dto) {
        AnalysisLineVO analysisLineVO = new AnalysisLineVO();
        List<AnalysisLineVO.DataList> dataList = new ArrayList<>();
       /* AnalysisLineVO.DataList list1 = new AnalysisLineVO.DataList();
        list1.setName("机关预算");
        list1.setType("line");
        list1.setYAxisData(new ArrayList<>());*/
        AnalysisLineVO.DataList list2 = new AnalysisLineVO.DataList();
        // list2.setName("承训单位预算");
        list2.setName("预算");
        list2.setType("line");
        list2.setYAxisData(new ArrayList<>());
        AnalysisLineVO.DataList list3 = new AnalysisLineVO.DataList();
        list3.setName("实际");
        list3.setType("line");
        list3.setYAxisData(new ArrayList<>());
        List<String> xAxisData = new ArrayList<>();
        // 获取当前年份
        List<String> yearList = DateUtils.getYearCollectionExample(6);
        List<Expense> list = expenseMapper.selectList(new LambdaQueryWrapper<Expense>()
                .eq(null != dto.getFlightId(), Expense::getFlightId, dto.getFlightId())
                .in(Expense::getYear, yearList));
        if (CollectionUtils.isEmpty(list)) {
            return analysisLineVO;
        }
        Map<String, List<Expense>> listMap = list.stream().collect(Collectors.groupingBy(Expense::getYear));
        for (String year : yearList) {
            xAxisData.add(year);
            List<Expense> expenses = listMap.get(year);
            if (CollectionUtils.isEmpty(expenses)) {
//                list1.getYAxisData().add("0");
                list2.getYAxisData().add("0");
                list3.getYAxisData().add("0");
            } else {
               /* list1.getYAxisData().add(String.valueOf(expenses.stream().map(l ->
                                BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(l.getOrganBudgetedAmount()) ?
                                        "0" : l.getOrganBudgetedAmount())))
                        .reduce(BigDecimal.ZERO, BigDecimal::add)));*/
                list2.getYAxisData().add(String.valueOf(expenses.stream().map(l ->
                                BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(l.getTrainingBudgetedAmount()) ?
                                        "0" : l.getTrainingBudgetedAmount())))
                        .reduce(BigDecimal.ZERO, BigDecimal::add)));
                list3.getYAxisData().add(String.valueOf(expenses.stream().map(l ->
                                BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(l.getSettlementAmount()) ?
                                        "0" : l.getSettlementAmount())))
                        .reduce(BigDecimal.ZERO, BigDecimal::add)));
            }
        }
        // dataList.add(list1);
        dataList.add(list2);
        dataList.add(list3);
        analysisLineVO.setXAxisData(xAxisData);
        analysisLineVO.setDataList(dataList);
        return analysisLineVO;
    }

    @Override
    public TypeStatisticsVO expenseType(ExpenseStatisticsDTO dto) {
        TypeStatisticsVO vo = new TypeStatisticsVO();
        List<LabelAndValueNameVO> voList = new ArrayList<>();
        List<Expense> list = expenseMapper.selectList(new LambdaQueryWrapper<Expense>()
                .eq(null != dto.getFlightId(), Expense::getFlightId, dto.getFlightId())
                .eq(null != dto.getTrainingTime(), Expense::getTrainingTime, dto.getTrainingTime())
                .eq(StringUtils.isBlank(dto.getYear()), Expense::getYear, Year.now().getValue())
                .eq(StringUtils.isNotBlank(dto.getYear()), Expense::getYear, dto.getYear()));
        if (CollectionUtils.isEmpty(list)) {
            voList.add(new LabelAndValueNameVO().setName("住宿费用").setValue("0"));
            voList.add(new LabelAndValueNameVO().setName("伙食费用").setValue("0"));
            voList.add(new LabelAndValueNameVO().setName("场地费用").setValue("0"));
            voList.add(new LabelAndValueNameVO().setName("其他费用").setValue("0"));
            voList.add(new LabelAndValueNameVO().setName("总费用").setValue("0"));
            vo.setTotal("0");
            vo.setLabels(voList);
            return vo;
        }
        voList.add(new LabelAndValueNameVO()
                .setName("住宿费用")
                .setValue(list.stream().map(l ->
                        BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(l.getAccommodationCost()) ?
                                "0" : l.getAccommodationCost()))
                ).reduce(BigDecimal.ZERO, BigDecimal::add).stripTrailingZeros().toPlainString()));
        voList.add(new LabelAndValueNameVO()
                .setName("伙食费用")
                .setValue(list.stream().map(l ->
                        BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(l.getBoardMoney()) ?
                                "0" : l.getBoardMoney()))
                ).reduce(BigDecimal.ZERO, BigDecimal::add).stripTrailingZeros().toPlainString()));
        voList.add(new LabelAndValueNameVO()
                .setName("场地费用")
                .setValue(list.stream().map(l ->
                        BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(l.getConferenceRoom()) ?
                                        "0" : l.getConferenceRoom()))
                                .add(BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(l.getProductionWorkshop()) ?
                                        "0" : l.getProductionWorkshop())))
                ).reduce(BigDecimal.ZERO, BigDecimal::add).stripTrailingZeros().toPlainString()));
        voList.add(new LabelAndValueNameVO()
                .setName("其他费用")
                .setValue(list.stream().map(l ->
                        BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(l.getOtherExpenses()) ?
                                "0" : l.getOtherExpenses()))
                ).reduce(BigDecimal.ZERO, BigDecimal::add).stripTrailingZeros().toPlainString()));
        vo.setTotal(list.stream().map(Expense::getTotal).reduce(BigDecimal.ZERO, BigDecimal::add).stripTrailingZeros().toPlainString());
        vo.setLabels(voList);
        return vo;
    }

    @Override
    public TypeStatisticsVO expenseUnit(ExpenseStatisticsDTO dto) {
        TypeStatisticsVO vo = new TypeStatisticsVO();
        List<LabelAndValueNameVO> voList = new ArrayList<>();
        List<Expense> list = expenseMapper.selectList(new LambdaQueryWrapper<Expense>()
                .eq(null != dto.getFlightId(), Expense::getFlightId, dto.getFlightId())
                .eq(StringUtils.isBlank(dto.getYear()), Expense::getYear, Year.now().getValue()));
        if (CollectionUtils.isEmpty(list)) {
            return vo;
        }
        Map<String, List<Expense>> map = list.stream().collect(Collectors.groupingBy(Expense::getTrainingUnitName));
        BigDecimal bigDecimal = BigDecimal.ZERO;
        map.keySet().forEach(m -> {
            BigDecimal reduce = map.get(m).stream().map(l ->
                    BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(l.getAccommodationCost()) ?
                            "0" : l.getAccommodationCost()))).reduce(BigDecimal.ZERO, BigDecimal::add);
            voList.add(new LabelAndValueNameVO()
                    .setName(m)
                    .setValue(String.valueOf(reduce)));
            bigDecimal.add(reduce);
        });
        vo.setTotal(String.valueOf(bigDecimal));
        vo.setLabels(voList);
        return vo;
    }

    @Override
    public TypeStatisticsVO expenseOperations(ExpenseStatisticsDTO dto) {
        TypeStatisticsVO vo = new TypeStatisticsVO();
        List<Expense> list = expenseMapper.selectList(new LambdaQueryWrapper<Expense>()
                .eq(null != dto.getFlightId(), Expense::getFlightId, dto.getFlightId())
                .eq(StringUtils.isBlank(dto.getYear()), Expense::getYear, Year.now().getValue())
                .eq(StringUtils.isNotBlank(dto.getYear()), Expense::getYear, dto.getYear()));
        if (CollectionUtils.isEmpty(list)) {
            return vo;
        }
        List<ExpenseStatVO> stats = new ArrayList<>();
        for (Expense expense : list) {
            Flight flight = flightMapper.selectOne(new LambdaQueryWrapper<Flight>()
                    .eq(Flight::getFlightId, expense.getFlightId()));
            ExpenseStatVO expenseStatVO = BeanUtil.copy(expense, ExpenseStatVO.class);
            expenseStatVO.setMainUnitName(flight.getMainUnitName());
            expenseStatVO.setMainUnitId(flight.getMainUnitId());
            stats.add(expenseStatVO);
        }
        Map<String, List<ExpenseStatVO>> statMap = stats.stream().collect(Collectors.groupingBy(ExpenseStatVO::getMainUnitName));
        BigDecimal total = new BigDecimal(0);
        List<LabelAndValueNameVO> labels = new ArrayList<>();
        statMap.keySet().forEach(k -> {
            BigDecimal costTotal = new BigDecimal(0);
            for (ExpenseStatVO expenseStatVO : statMap.get(k)) {
                BigDecimal bigDecimal = new BigDecimal(expenseStatVO.getSettlementAmount());
                total.add(bigDecimal);

                costTotal = statMap.get(k).stream().map(l ->
                        BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(l.getAccommodationCost()) ?
                                "0" : l.getAccommodationCost()))).reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            LabelAndValueNameVO labelAndValueNameVO = new LabelAndValueNameVO().setName(k).setValue(String.valueOf(costTotal));
            labels.add(labelAndValueNameVO);
        });
        vo.setTotal(String.valueOf(total));
        vo.setLabels(labels);
        return vo;

//         List<Unit> unitList = unitMapper.selectList(new LambdaQueryWrapper<Unit>().eq(Unit::getParentId, getUnitId()));
//         Map<Long, String> map = unitList.stream().collect(Collectors.toMap(Unit::getUnitId, Unit::getUnitName));
//         projectMapper.selectList(new LambdaQueryWrapper<Project>().in())
//         BigDecimal bigDecimal = BigDecimal.ZERO;
//         map.keySet().forEach(m ->{
//             BigDecimal reduce = map.get(m).stream().map(l ->
//                     BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(l.getAccommodationCost()) ?
//                             "0" : l.getAccommodationCost()))).reduce(BigDecimal.ZERO, BigDecimal::add);
//             voList.add(new LabelAndValueNameVO()
//                     .setName(m)
//                     .setValue(String.valueOf(reduce)));
//             bigDecimal.add(reduce);
//         });
//
//         voList.add(new LabelAndValueNameVO()
//                 .setName("总费用")
//                 .setValue(String.valueOf(bigDecimal)));
//        return vo;
    }

    @Override
    public AnalysisLineVO expensePerCapita(ExpenseStatisticsDTO dto) {
        AnalysisLineVO analysisLineVO = new AnalysisLineVO();
        List<AnalysisLineVO.DataList> dataList = new ArrayList<>();
       /* AnalysisLineVO.DataList list1 = new AnalysisLineVO.DataList();
        list1.setName("机关预算");
        list1.setType("line");
        list1.setYAxisData(new ArrayList<>());*/
        AnalysisLineVO.DataList list2 = new AnalysisLineVO.DataList();
        // list2.setName("承训单位预算");
        list2.setName("预算");
        list2.setType("line");
        list2.setYAxisData(new ArrayList<>());
        AnalysisLineVO.DataList list3 = new AnalysisLineVO.DataList();
        list3.setName("实际");
        list3.setType("line");
        list3.setYAxisData(new ArrayList<>());
        List<String> xAxisData = new ArrayList<>();
        // 获取当前年份
        List<String> yearList = DateUtils.getYearCollectionExample(6);
        List<Expense> list = expenseMapper.selectList(new LambdaQueryWrapper<Expense>()
                .eq(null != dto.getFlightId(), Expense::getFlightId, dto.getFlightId())
                .in(Expense::getYear, yearList));
        if (CollectionUtils.isEmpty(list)) {
            return analysisLineVO;
        }
        /*Long count = projectPersonnelInfoMapper.selectCount(new LambdaQueryWrapper<ProjectPersonnelInfo>()
                .eq(ProjectPersonnelInfo::getFlightId, dto.getFlightId()));*/
        Long count = studentInfoMapper.selectCount(new LambdaQueryWrapper<StudentInfo>()
                .in(StudentInfo::getYear, yearList)
                .eq(null != dto.getFlightId(), StudentInfo::getFlightId, dto.getFlightId()));
        Map<String, List<Expense>> listMap = list.stream().collect(Collectors.groupingBy(Expense::getYear));
        for (String year : yearList) {
            xAxisData.add(year);
            List<Expense> expenses = listMap.get(year);
            if (CollectionUtils.isEmpty(expenses) || 0 == count) {
                // list1.getYAxisData().add("0");
                list2.getYAxisData().add("0");
                list3.getYAxisData().add("0");
            } else {
                /*list1.getYAxisData().add(String.valueOf(expenses.stream().map(l ->
                                BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(l.getOrganBudgetedAmount()) ?
                                        "0" : l.getOrganBudgetedAmount())))
                        .reduce(BigDecimal.ZERO, BigDecimal::add)
                        .divide(BigDecimal.valueOf(count), 2, RoundingMode.HALF_UP)));*/
                list2.getYAxisData().add(String.valueOf(expenses.stream().map(l ->
                                BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(l.getTrainingBudgetedAmount()) ?
                                        "0" : l.getTrainingBudgetedAmount())))
                        .reduce(BigDecimal.ZERO, BigDecimal::add)
                        .divide(BigDecimal.valueOf(count), 2, RoundingMode.HALF_UP)));
                list3.getYAxisData().add(String.valueOf(expenses.stream().map(l ->
                                BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(l.getSettlementAmount()) ?
                                        "0" : l.getSettlementAmount())))
                        .reduce(BigDecimal.ZERO, BigDecimal::add)
                        .divide(BigDecimal.valueOf(count), 2, RoundingMode.HALF_UP)));
            }
        }
        // dataList.add(list1);
        dataList.add(list2);
        dataList.add(list3);
        analysisLineVO.setXAxisData(xAxisData);
        analysisLineVO.setDataList(dataList);
        return analysisLineVO;
    }

    @Override
    public NumberParticipantsVO flightNumberParticipants(ExpenseStatisticsDTO dto) {
        NumberParticipantsVO numberParticipantsVO = new NumberParticipantsVO();

        if (StringUtils.isNotNull(dto.getFlightId())) {
            Flight flight = flightMapper.selectVoById(dto.getFlightId());
            if (StringUtils.isNull(flight)) {
                return numberParticipantsVO;
            }
            numberParticipantsVO.setFlightName(flight.getFlightName() + "班");
            // 获取计划参训人数
        } else {
            if (StringUtils.isEmpty(dto.getYear())) {
                dto.setYear(DateUtils.dateTimeNow("YYYY"));
            }
            numberParticipantsVO.setFlightName(dto.getYear() + "年");
        }
        Long unitId = getUnitId();
        if (StringUtils.isNull(unitId)) {
            return numberParticipantsVO;
        }
        // 获取子级部门id
        List<Long> unitIdList = unitMapper.juniorUnit(unitId);
        unitIdList.remove(unitId);
        // 获取当前年份
        List<String> yearList = DateUtils.getYearsBefore(Integer.parseInt(dto.getYear()), 1);
        // 获取计划参训人数
        Integer planParticipate = projectMapper.getPlanParticipateNum(unitIdList, yearList, dto.getFlightId());
        numberParticipantsVO.setPlanParticipate(planParticipate);
        // 获取实际参训人数
        Integer actualParticipate = projectPersonnelInfoMapper.getActualParticipateNum(unitIdList, yearList, dto.getFlightId());
        numberParticipantsVO.setActualParticipate(actualParticipate);
        return numberParticipantsVO;
    }

    @Override
    public AnalysisLineVO flightTrainingCourseNum(ExpenseStatisticsDTO dto) {
        AnalysisLineVO analysisLineVO = new AnalysisLineVO();
        // 判断是否传年份
        if (StringUtils.isEmpty(dto.getYear())) {
            dto.setYear(DateUtils.dateTimeNow("YYYY"));
        }
        Long unitId = SecurityUtils.getUnitId();
        if (StringUtils.isNull(unitId)) {
            return analysisLineVO;
        }
        // 获取子级部门id
//        List<Long> unitIdList = unitMapper.juniorUnit(unitId);
        List<Long> unitIdList = new ArrayList<>();
        List<AnalysisLineVO.DataList> dataList = new ArrayList<>();
        AnalysisLineVO.DataList list = new AnalysisLineVO.DataList();
        list.setName("培训班数量");
        list.setType("line");
        list.setYAxisData(new ArrayList<>());
        List<String> xAxisData = new ArrayList<>();
        // 获取年份
        List<String> yearList = DateUtils.getYearsBefore(Integer.parseInt(dto.getYear()), 6);

/*        List<LabelAndValueVO> labelAndValueList = projectMapper.flightTrainingCourseNum(unitIdList, yearList);
        Map<String, String> map = new HashMap<>();
        if (!CollectionUtils.isEmpty(labelAndValueList)) {
            map = labelAndValueList.stream().collect(Collectors.toMap(LabelAndValueVO::getValue, LabelAndValueVO::getLabel));
        }*/

        Map<String, String> map = new HashMap<>();
        List<Flight> flights = flightMapper.selectList(new LambdaQueryWrapper<Flight>()
                .in(Flight::getYear, yearList)
                .eq(Flight::getCreateDept, getUnitId())
        );
        Map<String, List<Flight>> flightMap = flights.stream().collect(Collectors.groupingBy(Flight::getYear));

        flightMap.keySet().forEach(k -> {
            map.put(k, String.valueOf(flightMap.get(k).size()));
        });
        for (String year : yearList) {
            xAxisData.add(year);
            if (!CollectionUtils.isEmpty(map)) {
                list.getYAxisData().add(StringUtils.isNotEmpty(map.get(year)) ? map.get(year) : "0");
            } else {
                list.getYAxisData().add("0");
            }
        }
        dataList.add(list);
        analysisLineVO.setXAxisData(xAxisData);
        analysisLineVO.setDataList(dataList);
        return analysisLineVO;
    }

    @Override
    public List<LabelAndValueVO> flightNumProportion(ExpenseStatisticsDTO dto) {
        // 判断是否传年份
        if (StringUtils.isEmpty(dto.getYear())) {
            dto.setYear(DateUtils.dateTimeNow("YYYY"));
        }
        Long unitId = SecurityUtils.getUnitId();
        if (StringUtils.isNull(unitId)) {
            return new ArrayList<>();
        }
        // 获取年份
        List<String> yearList = DateUtils.getYearsBefore(Integer.parseInt(dto.getYear()), 1);
        // 获取子级部门id
//        List<Long> unitIdList = unitMapper.juniorUnit(unitId);
        List<Long> unitIdList = new ArrayList<>();
        return projectMapper.flightNumProportion(unitIdList, yearList);

    }

    @Override
    public FlightTrainingStatusVO flightTrainingStatus(ExpenseStatisticsDTO dto) {
        FlightTrainingStatusVO flightTrainingStatusVO = new FlightTrainingStatusVO();
        if (StringUtils.isEmpty(dto.getYear())) {
            dto.setYear(DateUtils.dateTimeNow("YYYY"));
        }
/*        Long unitId = SecurityUtils.getUnitId();
        if (StringUtils.isNull(unitId)) {
            return flightTrainingStatusVO;
        }
        //获取年份
        List<String> yearList = DateUtils.getYearsBefore(Integer.parseInt(dto.getYear()), 1);
        //获取子级部门id
//        List<Long> unitIdList = unitMapper.juniorUnit(unitId);
        List<Long> unitIdList = new ArrayList<>();
        List<LabelAndValueVO> labelAndValueList = projectPersonnelInfoMapper.FlightTrainingStatusVO(yearList, unitIdList);
        if (!CollectionUtils.isEmpty(labelAndValueList)) {
            int total = labelAndValueList.stream()
                    .mapToInt(labelAndValue -> {
                        try {
                            return Integer.parseInt(labelAndValue.getValue());  // 将字符串转换为整数
                        } catch (NumberFormatException e) {
                            return 0;  // 如果无法解析为整数，返回 0
                        }
                    })
                    .sum();
            flightTrainingStatusVO.setTotal(total);
            flightTrainingStatusVO.setLabels(labelAndValueList);
        }*/

        // 获取年份
        List<String> yearList = DateUtils.getYearsBefore(Integer.parseInt(dto.getYear()), 1);
        List<Flight> flights = flightMapper.selectList(new LambdaQueryWrapper<Flight>()
                .in(Flight::getYear, yearList)
                .eq(Flight::getCreateDept, getUnitId())
        );
        for (Flight flight : flights) {
            Date trainingTime = flight.getTrainingTime();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(trainingTime);
            calendar.add(Calendar.DATE, Integer.valueOf(flight.getEducationalSystem()));
            flight.setEndTime(calendar.getTime());
        }
        List<LabelAndValueVO> labelAndValueList = new ArrayList<>();
        long count = flights.stream().filter(flight -> new Date().compareTo(flight.getTrainingTime()) < 0).toList().size();
        LabelAndValueVO labelAndValueVO = new LabelAndValueVO();
        labelAndValueVO.setLabel("未培训");
        labelAndValueVO.setValue(String.valueOf(count));
        labelAndValueList.add(labelAndValueVO);

        long count1 = flights.stream().filter(flight -> flight.getTrainingTime().compareTo(new Date()) < 0 && flight.getEndTime().compareTo(new Date()) > 0).toList().size();
        LabelAndValueVO labelAndValueVO1 = new LabelAndValueVO();
        labelAndValueVO1.setLabel("培训中");
        labelAndValueVO1.setValue(String.valueOf(count1));
        labelAndValueList.add(labelAndValueVO1);

        long count2 = flights.stream().filter(flight -> flight.getEndTime().compareTo(new Date()) < 0).toList().size();
        LabelAndValueVO labelAndValueVO2 = new LabelAndValueVO();
        labelAndValueVO2.setLabel("已培训");
        labelAndValueVO2.setValue(String.valueOf(count2));
        labelAndValueList.add(labelAndValueVO2);

        flightTrainingStatusVO.setTotal(flights.size());
        flightTrainingStatusVO.setLabels(labelAndValueList);

        return flightTrainingStatusVO;
    }

    @Override
    public FlightTrainingStatusVO flightNumProportion2(ExpenseStatisticsDTO dto) {
        FlightTrainingStatusVO flightTrainingStatusVO = new FlightTrainingStatusVO();
        List<LabelAndValueVO> voList = new ArrayList<>();
        // 判断是否传年份
        if (StringUtils.isEmpty(dto.getYear())) {
            dto.setYear(DateUtils.dateTimeNow("YYYY"));
        }
        // 获取年份
        List<String> yearList = DateUtils.getYearsBefore(Integer.parseInt(dto.getYear()), 1);
        List<Flight> flights = flightMapper.selectList(new LambdaQueryWrapper<Flight>()
                .in(Flight::getYear, yearList)
                .eq(Flight::getCreateDept, getUnitId())
        );
        int count = 0;
        int count1 = 0;
        int count2 = 0;
        int count3 = 0;
        int count4 = 0;
        int count5 = 0;
        for (Flight flight : flights) {
/*            List<StudentInfo> list = studentInfoMapper.selectList(new LambdaQueryWrapper<StudentInfo>()
                    .eq(StudentInfo::getFlightId,flight.getFlightId())
            );*/
            if (StringUtils.isNotEmpty(flight.getTrainingPost())) {
                int num = Integer.parseInt(flight.getTrainingPost());
                if (num < 10) {
                    count++;
                } else if (num < 20) {
                    count1++;
                } else if (num < 30) {
                    count2++;
                } else if (num < 40) {
                    count3++;
                } else if (num < 50) {
                    count4++;
                } else {
                    count5++;
                }
            }
        }
        voList.add(new LabelAndValueVO().setLabel("0-10").setValue(String.valueOf(count)));
        voList.add(new LabelAndValueVO().setLabel("10-20").setValue(String.valueOf(count1)));
        voList.add(new LabelAndValueVO().setLabel("20-30").setValue(String.valueOf(count2)));
        voList.add(new LabelAndValueVO().setLabel("30-40").setValue(String.valueOf(count3)));
        voList.add(new LabelAndValueVO().setLabel("40-50").setValue(String.valueOf(count4)));
        voList.add(new LabelAndValueVO().setLabel("50人以上").setValue(String.valueOf(count5)));
        flightTrainingStatusVO.setLabels(voList);
        flightTrainingStatusVO.setTotal(flights.size());

        return flightTrainingStatusVO;
    }

    @Override
    public List<LabelAndValueVO> flightTrainingType(ExpenseStatisticsDTO dto) {
/*        if (StringUtils.isEmpty(dto.getYear())) {
            dto.setYear(DateUtils.dateTimeNow("YYYY"));
        }
        Long unitId = SecurityUtils.getUnitId();
        if (StringUtils.isNull(unitId)) {
            return new ArrayList<>();
        }
        //获取年份
        List<String> yearList = DateUtils.getYearsBefore(Integer.parseInt(dto.getYear()), 1);
        //获取子级部门id
//        List<Long> unitIdList = unitMapper.juniorUnit(unitId);
        List<Long> unitIdList = new ArrayList<>();
        return flightMapper.flightTrainingType(dto.getYear(), unitIdList);*/
        if (StringUtils.isEmpty(dto.getYear())) {
            dto.setYear(DateUtils.dateTimeNow("YYYY"));
        }

        List<LabelAndValueVO> list = new ArrayList<>();
        List<SysDictData> data = dictDataMapper.selectList(
                new LambdaQueryWrapper<SysDictData>()
                        .eq(SysDictData::getDictType, "2")
                        .orderByDesc(SysDictData::getDictLabel));
        Map<String, String> labelMap = data.stream()
                .collect(Collectors.toMap(SysDictData::getDictLabel, SysDictData::getDictValue));
        labelMap.keySet().forEach(k -> {
            int count = flightMapper.selectList(new LambdaQueryWrapper<Flight>().like(Flight::getType, k)).size();
            LabelAndValueVO labelAndValueVO = new LabelAndValueVO();
            labelAndValueVO.setLabel(labelMap.get(k));
            labelAndValueVO.setValue(String.valueOf(count));
            list.add(labelAndValueVO);
        });
        return list;
    }

    @Override
    public AnalysisLineVO flightDistributionTrainees(ExpenseStatisticsDTO dto) {
        AnalysisLineVO analysisLineVO = new AnalysisLineVO();
        if (StringUtils.isNull(dto.getFlightId())) {
            return analysisLineVO;
        }
        if (StringUtils.isEmpty(dto.getYear())) {
            dto.setYear(DateUtils.dateTimeNow("YYYY"));
        }
        List<AnalysisLineVO.DataList> dataList = new ArrayList<>();
        AnalysisLineVO.DataList list1 = new AnalysisLineVO.DataList();
        list1.setName("计划");
        list1.setType("line");
        list1.setYAxisData(new ArrayList<>());
        AnalysisLineVO.DataList list2 = new AnalysisLineVO.DataList();
        list2.setName("实际");
        list2.setType("line");
        list2.setYAxisData(new ArrayList<>());
        List<String> xAxisData = new ArrayList<>();
        List<Unit> units = unitMapper.selectList(new LambdaQueryWrapper<Unit>()
                .eq(Unit::getParentId, getUnitId()));
        if (CollectionUtils.isEmpty(units)) {
            return analysisLineVO;
        }
        for (Unit unit : units) {
            xAxisData.add(unit.getUnitName());
            List<Project> list = projectMapper.selectList(new LambdaQueryWrapper<Project>()
                    .eq(Project::getCreateDept, unit.getUnitId())
                    .eq(Project::getYear, dto.getYear()));
            if (org.apache.commons.collections4.CollectionUtils.isEmpty(list)) {
                list1.getYAxisData().add("0");
                list2.getYAxisData().add("0");
            } else {
                list1.getYAxisData().add(String.valueOf(list.stream().map(l ->
                                BigDecimal.valueOf(Double.parseDouble(StringUtils.isEmpty(l.getTrainingPost()) ?
                                        "0" : l.getTrainingPost())))
                        .reduce(BigDecimal.ZERO, BigDecimal::add)));
                List<Long> ids = new ArrayList<>(list.stream().map(Project::getProjectId).toList());
                List<Project> all = getAll(ids);
                ids.addAll(all.stream().map(Project::getProjectId).toList());
                List<ProjectPersonnelInfo> list3 = projectPersonnelInfoMapper.selectList(new LambdaQueryWrapper<ProjectPersonnelInfo>()
                        .in(ProjectPersonnelInfo::getProjectId, ids));
                list2.getYAxisData().add(String.valueOf(list3.size()));
            }
        }
        dataList.add(list1);
        dataList.add(list2);
        analysisLineVO.setXAxisData(xAxisData);
        analysisLineVO.setDataList(dataList);

        return analysisLineVO;
    }

    @Override
    public FlightDistributionProportionVO flightDistributionProportion(ExpenseStatisticsDTO dto) {
        FlightDistributionProportionVO proportionVO = new FlightDistributionProportionVO();
        if (StringUtils.isNull(dto.getFlightId())) {
            return proportionVO;
        }
        if (StringUtils.isEmpty(dto.getYear())) {
            dto.setYear(DateUtils.dateTimeNow("YYYY"));
        }
        List<LabelAndValueVO> labelAndValueList = projectPersonnelInfoMapper.flightDistributionProportion(dto.getFlightId(), dto.getYear());
        if (!CollectionUtils.isEmpty(labelAndValueList)) {
            int total = labelAndValueList.stream()
                    .mapToInt(labelAndValue -> {
                        try {
                            return Integer.parseInt(labelAndValue.getValue());  // 将字符串转换为整数
                        } catch (NumberFormatException e) {
                            return 0;  // 如果无法解析为整数，返回 0
                        }
                    })
                    .sum();
            proportionVO.setTotal(total);
            proportionVO.setLabels(labelAndValueList);
        }
        return proportionVO;
    }

    @Override
    public AnalysisLineVO flightAnnualExcellenceRate(ExpenseStatisticsDTO dto) {
        AnalysisLineVO analysisLineVO = new AnalysisLineVO();
        List<AnalysisLineVO.DataList> dataList = new ArrayList<>();
        AnalysisLineVO.DataList list = new AnalysisLineVO.DataList();
        list.setName("历年优秀率");
        list.setType("line");
        list.setYAxisData(new ArrayList<>());
        List<String> xAxisData = new ArrayList<>();
        if (StringUtils.isNull(dto.getFlightId())) {
            return analysisLineVO;
        }
        // 获取当前班次的班次类型
        Flight flight = flightMapper.selectById(dto.getFlightId());
        if (StringUtils.isNull(flight) || StringUtils.isNull(flight.getMajorType())) {
            return analysisLineVO;
        }
        String majorType = flight.getMajorType();
        if (StringUtils.isEmpty(dto.getYear())) {
            dto.setYear(DateUtils.dateTimeNow("YYYY"));
        }
        // 获取年份
        List<String> yearList = DateUtils.getYearsBefore(Integer.parseInt(dto.getYear()), 6);
        List<LabelAndValueVO> flightAnnualExcellenceRateList = projectPersonnelInfoMapper.flightAnnualExcellenceRate(yearList, majorType);
        Map<String, String> map = new HashMap<>();
        if (!CollectionUtils.isEmpty(flightAnnualExcellenceRateList)) {
            map = flightAnnualExcellenceRateList.stream().collect(Collectors.toMap(LabelAndValueVO::getValue, LabelAndValueVO::getLabel));
        }
        for (String year : yearList) {
            xAxisData.add(year);
            if (!CollectionUtils.isEmpty(map)) {
                list.getYAxisData().add(StringUtils.isNotEmpty(map.get(year)) ? map.get(year) : "0");
            } else {
                list.getYAxisData().add("0");
            }
        }
        dataList.add(list);
        analysisLineVO.setXAxisData(xAxisData);
        analysisLineVO.setDataList(dataList);
        return analysisLineVO;
    }

    @Override
    public List<LabelAndValueVO> flightProportionGrades(ExpenseStatisticsDTO dto) {
        if (StringUtils.isNull(dto.getFlightId())) {
            return new ArrayList<>();
        }
        if (StringUtils.isEmpty(dto.getYear())) {
            dto.setYear(DateUtils.dateTimeNow("YYYY"));
        }
        // 获取年份
        List<String> yearList = DateUtils.getYearsBefore(Integer.parseInt(dto.getYear()), 1);
        return projectPersonnelInfoMapper.flightProportionGrades(yearList, dto.getFlightId());
    }

    @Override
    public AnalysisLineVO flightExpenseSettlement(ExpenseStatisticsDTO dto) {
        AnalysisLineVO analysisLineVO = new AnalysisLineVO();
        List<AnalysisLineVO.DataList> dataList = new ArrayList<>();
        AnalysisLineVO.DataList list = new AnalysisLineVO.DataList();
        list.setName("预算");
        list.setType("column");
        list.setYAxisData(new ArrayList<>());
        AnalysisLineVO.DataList list1 = new AnalysisLineVO.DataList();
        list1.setName("结算");
        list1.setType("column");
        list1.setYAxisData(new ArrayList<>());
        List<String> xAxisData = new ArrayList<>();
        if (StringUtils.isNull(dto.getFlightId())) {
            return analysisLineVO;
        }
        // 获取当前班次的班次类型
        Flight flight = flightMapper.selectById(dto.getFlightId());
        if (StringUtils.isNull(flight) || StringUtils.isNull(flight.getMajorType())) {
            return analysisLineVO;
        }
        String majorType = flight.getMajorType();
        if (StringUtils.isEmpty(dto.getYear())) {
            dto.setYear(DateUtils.dateTimeNow("YYYY"));
        }
        // 获取年份
        List<String> yearList = DateUtils.getYearsBefore(Integer.parseInt(dto.getYear()), 6);
        // 获取预算费用
        List<LabelAndValueVO> estimatedCostList = demandMapper.estimatedCost(majorType, yearList);
        Map<String, String> estimatedCostMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(estimatedCostList)) {
            estimatedCostMap = estimatedCostList.stream().collect(Collectors.toMap(LabelAndValueVO::getValue, LabelAndValueVO::getLabel));
        }
        // 获取结算费用
        List<LabelAndValueVO> settlementCostList = demandMapper.settlementCost(majorType, yearList);
        Map<String, String> settlementCostMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(settlementCostList)) {
            settlementCostMap = settlementCostList.stream().collect(Collectors.toMap(LabelAndValueVO::getValue, LabelAndValueVO::getLabel));
        }
        for (String year : yearList) {
            xAxisData.add(year);
            if (!CollectionUtils.isEmpty(estimatedCostMap)) {
                list.getYAxisData().add(StringUtils.isNotEmpty(estimatedCostMap.get(year)) ? estimatedCostMap.get(year) : "0");
            } else {
                list.getYAxisData().add("0");
            }
            if (!CollectionUtils.isEmpty(settlementCostMap)) {
                list1.getYAxisData().add(StringUtils.isNotEmpty(settlementCostMap.get(year)) ? settlementCostMap.get(year) : "0");
            } else {
                list1.getYAxisData().add("0");
            }
        }
        dataList.add(list);
        dataList.add(list1);
        analysisLineVO.setXAxisData(xAxisData);
        analysisLineVO.setDataList(dataList);
        return analysisLineVO;
    }

    public List<Project> getAll(List<Long> ids) {
        List<Project> list = new ArrayList<>();
        List<Project> projects = projectMapper.selectList(new LambdaQueryWrapper<Project>()
                .in(Project::getParentId, ids));
        if (CollectionUtils.isEmpty(projects)) {
            return list;
        }
        list.addAll(projects);
        list.addAll(getAll(projects.stream().map(Project::getProjectId).distinct().toList()));
        return list;
    }
}
