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

import com.xinyilu.common.constant.Constants;
import com.xinyilu.common.core.domain.AjaxResult;
import com.xinyilu.common.core.domain.entity.SysRole;
import com.xinyilu.common.core.page.TableDataInfo;
import com.xinyilu.common.exception.ServiceException;
import com.xinyilu.common.utils.AgeUtil;
import com.xinyilu.common.utils.DateUtils;
import com.xinyilu.common.utils.PageServiceUtil;
import com.xinyilu.common.utils.SecurityUtils;
import com.xinyilu.system.domain.classinfo.ClassInfo;
import com.xinyilu.system.domain.dto.ClassInfoDTO;
import com.xinyilu.system.domain.dto.ImportTestProjectScoresDTO;
import com.xinyilu.system.domain.dto.ItemStudentScoreDTO;
import com.xinyilu.system.domain.dto.TestItemScoreInfoUpdateDTO;
import com.xinyilu.system.domain.studentInfo.StudentInfo;
import com.xinyilu.system.domain.systemarea.SysArea;
import com.xinyilu.system.domain.sysuserclassrelation.SysUserClassRelation;
import com.xinyilu.system.domain.testItemScoreinfo.TestItemScore;
import com.xinyilu.system.domain.testItemStandard.TestItemStandard;
import com.xinyilu.system.domain.vo.*;
import com.xinyilu.system.domain.vo.testItemAvgScore.TestStudentFractionVO;
import com.xinyilu.system.mapper.SysUserMapper;
import com.xinyilu.system.mapper.classinfo.ClassInfoMapper;
import com.xinyilu.system.mapper.kindergarteninfo.KindergartenInfoMapper;
import com.xinyilu.system.mapper.studentInfo.StudentInfoMapper;
import com.xinyilu.system.mapper.systemarea.SysAreaMapper;
import com.xinyilu.system.mapper.sysuserclassrelation.SysUserClassRelationMapper;
import com.xinyilu.system.mapper.testItem.TestItemsMapper;
import com.xinyilu.system.mapper.testItemScoreinfo.TestItemScoreMapper;
import com.xinyilu.system.mapper.testItemStandard.TestItemStandardMapper;
import com.xinyilu.system.service.testItemScoreinfo.ITestItemScoreService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 个人成绩录入管理Service业务层处理
 *
 * @author xinyilu
 * @date 2022-08-04
 */
@Service
public class TestItemScoreServiceImpl implements ITestItemScoreService {
    @Resource
    private TestItemScoreMapper testItemScoreMapper;
    @Resource
    private PageServiceUtil pageServiceUtil;
    @Resource
    private TestItemStandardMapper testItemStandardMapper;
    @Resource
    private TestItemsMapper testItemsMapper;
    @Resource
    private ClassInfoMapper classInfoMapper;
    @Resource
    private StudentInfoMapper studentInfoMapper;
    @Resource
    private SysUserClassRelationMapper sysUserClassRelationMapper;
    @Resource
    private SysUserMapper userMapper;
    @Resource
    private KindergartenInfoMapper kindergartenInfoMapper;
    @Resource
    private SysAreaMapper sysAreaMapper;

    /**
     * 体重项目名称
     */
    private static final String WEIGHT_NAME = "体重";

    /**
     * 查询个人成绩录入管理
     *
     * @param studentId 学生id
     * @param batchCode 批次编号
     * @return 个人成绩录入管理
     */
    @Override
    public AjaxResult selectTestItemScoreById(Long studentId, String batchCode) {
        //查询该批次对应的成绩信息
        List<TestItemScoreUpdateVO> testItemScoreList = testItemScoreMapper.selectTestItemScoreById(studentId, batchCode);
        if (CollectionUtils.isEmpty(testItemScoreList)) {
            AjaxResult.success();
        }
        //组装数据
        TestItemScoreUpdateVO updateVO = new TestItemScoreUpdateVO();
        //设置学生班级基本信息
        if (testItemScoreList.size() > 0) {
            updateVO.setClassId(Objects.isNull(testItemScoreList.get(0).getClassId()) ? null : testItemScoreList.get(0).getClassId());
            updateVO.setStudentId(Objects.isNull(testItemScoreList.get(0).getStudentId()) ? null : testItemScoreList.get(0).getStudentId());
            updateVO.setStudentName(StringUtils.isBlank(testItemScoreList.get(0).getStudentName()) ? "" : testItemScoreList.get(0).getStudentName());
            updateVO.setBatchCode(StringUtils.isBlank(testItemScoreList.get(0).getBatchCode()) ? "" : testItemScoreList.get(0).getBatchCode());
        }
        //设置测试项目成绩信息
        List<ItemStudentScoreDTO> itemScoreList = testItemScoreList.stream().filter(Objects::nonNull).map(item -> {
            ItemStudentScoreDTO dto = new ItemStudentScoreDTO();
            dto.setId(Objects.isNull(item.getId()) ? null : item.getId());
            dto.setTestItemId(Objects.isNull(item.getTestItemId()) ? null : item.getTestItemId());
            dto.setItemCode(StringUtils.isBlank(item.getItemCode()) ? null : item.getItemCode());
            dto.setItemName(StringUtils.isBlank(item.getItemName()) ? null : item.getItemName());
            dto.setScoreDictId(Objects.isNull(item.getScoreDictId()) ? null : item.getScoreDictId());
            dto.setScoreDictValue(StringUtils.isBlank(item.getScoreDictValue()) ? null : item.getScoreDictValue());
            dto.setItemScore(Objects.isNull(item.getItemScore()) ? null : item.getItemScore());
            dto.setItemFraction(Objects.isNull(item.getItemFraction()) ? null : item.getItemFraction());
            dto.setSyntheticalAssess(StringUtils.isBlank(item.getSyntheticalAssess()) ? null : item.getSyntheticalAssess());
            return dto;
        }).collect(Collectors.toList());
        //查询该批次下得所有项目信息
        List<ItemStudentScoreDTO> testBatchItemInfoList = testItemScoreMapper.getTestBatchItemInfoList(batchCode);
        //找出当前批次下新增的测试项目信息
        List<ItemStudentScoreDTO> subtractList = (List<ItemStudentScoreDTO>) CollectionUtils.subtract(testBatchItemInfoList, itemScoreList);
        if (CollectionUtils.isNotEmpty(subtractList)) {
            itemScoreList.addAll(subtractList);
        }
        updateVO.setItemScoreList(itemScoreList);
        return AjaxResult.success(updateVO);
    }

    /**
     * 查询个人成绩录入管理列表
     *
     * @param testItemScore 个人成绩录入管理
     * @return 个人成绩录入管理
     */
    @Override
    public TableDataInfo selectTestItemScoreList(TestItemScoreinfoVO testItemScore) {
        //判断当前用户所属角色，根据角色显示对应数据信息
        List<String> roleKeys = SecurityUtils.getLoginUser().getUser().getRoles()
                .stream().filter(Objects::nonNull)
                .filter(item -> StringUtils.isNotBlank(item.getRoleKey()))
                .map(SysRole::getRoleKey).collect(Collectors.toList());
        Long userId = SecurityUtils.getUserId();
        SysUserVO sysUserVO = userMapper.selectUserById(userId);
        if (roleKeys.contains(Constants.ADMIN_ROLE)) {
            //角色为管理员，查询所有幼儿园信息
            return getTestItemInfoList(testItemScore);
        } else if (roleKeys.contains(Constants.CITY)) {
            //角色为市级角色，查询该市级下的所有幼儿园中的所有学生信息信息
            long areaId = Objects.isNull(SecurityUtils.getLoginUser().getUser().getAreaId()) ? 0 : SecurityUtils.getLoginUser().getUser().getAreaId();
            SysArea sysArea = new SysArea();
            sysArea.setParentId(areaId);
            List<Long> sysAreaIdList = sysAreaMapper.selectSysAreaList(sysArea).stream().filter(Objects::nonNull).filter(sysAreaId -> Objects.nonNull(sysAreaId.getId())).map(SysArea::getId).collect(Collectors.toList());
            List<Long> kindergartenIdList = Lists.newArrayList();
            if (CollectionUtils.isNotEmpty(sysAreaIdList)) {
                //获取该区域下的所有幼儿园信息
                kindergartenIdList = classInfoMapper.getKindergartenInfoByAreaId(sysAreaIdList, null);
            }
            if (CollectionUtils.isEmpty(kindergartenIdList)) {
                return null;
            }
            //找出当前市下所有幼儿园下的所有班级信息
            List<Long> classIdList = studentInfoMapper.getClassIdByKindergartenIdList(kindergartenIdList);
            testItemScore.setClassIdList(classIdList);
            return getTestItemInfoList(testItemScore);
        } else if (roleKeys.contains(Constants.REGION_ROLE)) {
            //角色为区域角色，查询该区域内的所有幼儿园的信息
            long areaId = Objects.isNull(SecurityUtils.getLoginUser().getUser().getAreaId()) ? 0 : SecurityUtils.getLoginUser().getUser().getAreaId();
            List<Long> classIdList = Lists.newArrayList();
            if (areaId != 0) {
                classIdList = testItemScoreMapper.getSysAreaIdByParentId(areaId);
            }
            if (CollectionUtils.isEmpty(classIdList)) {
                return null;
            }
            testItemScore.setClassIdList(classIdList);
            return getTestItemInfoList(testItemScore);
        } else if (roleKeys.contains(Constants.ENCHOU_ROLE)) {
            //角色是：园长，查询自己幼儿园的信息 获取响应班级的信息
            List<Long> classIdList = testItemScoreMapper.getClassInfoIdByParentId(userId);
            if (CollectionUtils.isEmpty(classIdList)) {
                return null;
            }
            testItemScore.setClassIdList(classIdList);
            return getTestItemInfoList(testItemScore);
        } else if (roleKeys.contains(Constants.HEALTHCARE_ROLE)) {
            //角色是：保健师，查找出其所属的幼儿园信息
            if (Objects.isNull(sysUserVO) || Objects.isNull(sysUserVO.getKindergartenId())) {
                return null;
            }
            ClassInfoDTO classInfo = new ClassInfoDTO();
            classInfo.setKindergartenId(sysUserVO.getKindergartenId());
            List<Long> classIdLists = classInfoMapper.selectClassInfoList(classInfo).stream().filter(Objects::nonNull).filter(classId -> Objects.nonNull(classId.getId())).map(ClassInfoVO::getId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(classIdLists)) {
                return null;
            }
            testItemScore.setClassIdList(classIdLists);
            return getTestItemInfoList(testItemScore);
        } else if (roleKeys.contains(Constants.TEACHER_ROLE) && roleKeys.size() == 1) {
            //角色是：老师，查找出其所属的班级id
            List<Long> classIdList = sysUserClassRelationMapper.getSysUserClassRelationList(userId).stream().filter(Objects::nonNull).filter(classId -> Objects.nonNull(classId.getClassId())).map(SysUserClassRelation::getClassId).distinct().collect(Collectors.toList());
            if (CollectionUtils.isEmpty(classIdList)) {
                return null;
            }
            testItemScore.setClassIdList(classIdList);
            return getTestItemInfoList(testItemScore);
        } else if (roleKeys.contains(Constants.PARENT_ROLE) && roleKeys.size() == 1) {
            //角色是：家长，查找出其学生的id
            if (Objects.isNull(sysUserVO) || Objects.isNull(sysUserVO.getPhonenumber())) {
                return null;
            }
            List<Long> studentIdList = testItemScoreMapper.getStudentInfoIdByParentId(sysUserVO.getPhonenumber());
            if (CollectionUtils.isEmpty(studentIdList)) {
                return null;
            }
            testItemScore.setIdList(studentIdList);
            return getTestItemInfoList(testItemScore);
        } else if (roleKeys.contains(Constants.TEACHER_ROLE) && roleKeys.contains(Constants.PARENT_ROLE) && roleKeys.size() == 2) {
            //角色即是家长又是老师，分别查询出老师和家长所属的幼儿园表的id
            List<Long> studentList = new ArrayList<>();
            List<Long> classList = sysUserClassRelationMapper.getSysUserClassRelationList(userId).stream().filter(Objects::nonNull).filter(classId -> Objects.nonNull(classId.getClassId())).map(SysUserClassRelation::getClassId).distinct().collect(Collectors.toList());
            if (Objects.nonNull(sysUserVO) && Objects.nonNull(sysUserVO.getPhonenumber())) {
                studentList = testItemScoreMapper.getStudentInfoIdByParentId(sysUserVO.getPhonenumber());
            }
            if (CollectionUtils.isEmpty(studentList) && CollectionUtils.isEmpty(classList)) {
                return null;
            }
            testItemScore.setClassList(classList);
            testItemScore.setStudentList(studentList);
            return getTestItemInfoList(testItemScore);
        }
        return null;
    }


    /**
     * 新增个人成绩录入管理
     *
     * @param testItemScore 个人成绩录入管理
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertTestItemScore(TestItemScoreInfoUpdateDTO testItemScore) {
        //测试项目信息
        if (CollectionUtils.isEmpty(testItemScore.getItemScoreList())) {
            return AjaxResult.error("测试项目成绩信息不能为空！");
        }
        // 获取项目id
        List<Long> itemIdList = testItemScore.getItemScoreList().stream().filter(item -> Objects.nonNull(item.getTestItemId())).distinct().map(ItemStudentScoreDTO::getTestItemId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(itemIdList)) {
            return AjaxResult.error("测试项目成绩信息不能为空！");
        }
        List<TestItemStandard> testItemStandardList = testItemStandardMapper.getItemStandardByItemIds(itemIdList);
        if (CollectionUtils.isEmpty(testItemStandardList)) {
            return AjaxResult.error("该项目信息不存在");
        }
        // 校验测试项目成绩
        AjaxResult ajaxResult = this.judgeItemScore(testItemStandardList, testItemScore.getItemScoreList());
        if (Objects.nonNull(ajaxResult)) {
            return ajaxResult;
        }
        // 删除原有该项目的录入成绩
        List<Long> testItemIdList = testItemScoreMapper.getAllTestItemId(testItemScore.getStudentId(), itemIdList, testItemScore.getBatchCode());
        if (testItemIdList.size() > 0) {
            int itemById = testItemScoreMapper.deleteTestItemById(testItemIdList);
            if (itemById <= 0) {
                throw new ServiceException("删除测试项目成绩信息失败");
            }
        }
        //设置新增测试项目成绩信息
        List<TestItemScore> testItemScoreList = this.setCreateTestItemScoreInfo(testItemScore);
        if (CollectionUtils.isNotEmpty(testItemScoreList)) {
            int insertCount = testItemScoreMapper.insertTestItemScoreList(testItemScoreList);
            if (insertCount <= 0) {
                throw new ServiceException("新增测试项目个人成绩信息失败");
            }
        }
        return AjaxResult.success();
    }


    /**
     * 修改个人成绩录入管理
     *
     * @param testItemScore 个人成绩录入管理
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updateTestItemScore(TestItemScoreInfoUpdateDTO testItemScore) {
        //测试项目信息
        if (CollectionUtils.isEmpty(testItemScore.getItemScoreList())) {
            return AjaxResult.error("测试项目成绩信息不能为空！");
        }
        // 获取项目id
        List<Long> itemIdList = testItemScore.getItemScoreList().stream().filter(item -> Objects.nonNull(item.getTestItemId())).distinct().map(ItemStudentScoreDTO::getTestItemId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(itemIdList)) {
            return AjaxResult.error("测试项目成绩信息不能为空！");
        }
        List<TestItemStandard> testItemStandardList = testItemStandardMapper.getItemStandardByItemIds(itemIdList);
        if (CollectionUtils.isEmpty(testItemStandardList)) {
            return AjaxResult.error("该项目信息不存在");
        }
        // 校验测试项目成绩
        AjaxResult ajaxResult = judgeItemScore(testItemStandardList, testItemScore.getItemScoreList());
        if (Objects.nonNull(ajaxResult)) {
            return ajaxResult;
        }
        //更新项目成绩信息
        this.updateTestItemScoreInfo(testItemScore);
        return AjaxResult.success();
    }

    /**
     * 删除个人成绩录入管理信息
     *
     * @param id 个人成绩录入管理主键
     * @return 结果
     */
    @Override
    public int deleteTestItemScoreById(Long id) {
        return testItemScoreMapper.deleteTestItemScoreById(id);
    }

    /**
     * 逻辑批量删除个人成绩录入管理
     *
     * @param studentId 学生id
     * @param batchCode 批次编号
     * @return 结果
     */
    @Override
    public int updateTestItemScoreByIds(Long studentId, String batchCode) {
        return testItemScoreMapper.updateTestItemScoreByIds(studentId, batchCode);
    }

    /**
     * 获取个人成绩的信息
     *
     * @param studentId 学生id
     * @param batchId   批次id
     * @param batchCode 批次编号
     * @return com.xinyilu.common.core.domain.AjaxResult
     **/
    @Override
    public AjaxResult getAllTestItemScoreInfo(Long studentId, Long batchId, String batchCode) {
        //查询批次关联项目信息
        List<ShowItemBatchScoreVO> itemBatchScoreList = testItemScoreMapper.getAllTestItemScoreInfo(batchId, batchCode);
        if (CollectionUtils.isEmpty(itemBatchScoreList)) {
            return AjaxResult.error("该批次没有绑定的项目信息！");
        }
        //查询该学校的批次成绩信息
        List<ShowItemBatchScoreVO> testItemScoreList = testItemScoreMapper.getTestItemScoreByStudent(studentId, batchCode);
        if (CollectionUtils.isEmpty(testItemScoreList)) {
            itemBatchScoreList.forEach(item -> {
                item.setItemScore(null);
                item.setScoreDictValue(null);
                item.setItemFraction(null);
                item.setSyntheticalAssess(null);
            });
        } else {
            Map<Long, ShowItemBatchScoreVO> batchScoreMap = testItemScoreList.stream().filter(item -> Objects.nonNull(item.getItemId())).collect(Collectors.toMap(ShowItemBatchScoreVO::getItemId, item -> item));
            itemBatchScoreList.forEach(item -> {
                ShowItemBatchScoreVO showItemBatchScoreVO = batchScoreMap.getOrDefault(Objects.isNull(item.getItemId()) ? 0L : item.getItemId(), null);
                if (Objects.isNull(showItemBatchScoreVO)) {
                    item.setItemScore(null);
                    item.setScoreDictValue(null);
                    item.setItemFraction(null);
                    item.setSyntheticalAssess(null);
                } else {
                    item.setItemScore(Objects.isNull(showItemBatchScoreVO.getItemScore()) ? null : showItemBatchScoreVO.getItemScore());
                    item.setScoreDictValue(StringUtils.isBlank(showItemBatchScoreVO.getScoreDictValue()) ? null : showItemBatchScoreVO.getScoreDictValue());
                    item.setItemFraction(Objects.isNull(showItemBatchScoreVO.getItemFraction()) ? null : showItemBatchScoreVO.getItemFraction());
                    item.setSyntheticalAssess(StringUtils.isBlank(showItemBatchScoreVO.getSyntheticalAssess()) ? null : showItemBatchScoreVO.getSyntheticalAssess());
                }
            });
        }
        return AjaxResult.success(itemBatchScoreList);
    }


    /**
     * 根据学生的信息查询表中的信息自动匹配得分
     *
     * @param studentId   学生id
     * @param itemId      项目id
     * @param itemScore   项目得分
     * @param hwfFraction 体重项目成绩，只有项目为体重的时候才会传值
     * @return com.xinyilu.system.domain.vo.testItemAvgScore.TestStudentFractionVO
     **/
    @Override
    public AjaxResult getStudentFraction(Long studentId, Long itemId, BigDecimal itemScore, BigDecimal hwfFraction) {
        //首先根据学生id查询学生基本信息，年龄，性别，出生日期，
        TestStudentFractionVO studentFraction = testItemScoreMapper.getStudentFraction(studentId);
        if (Objects.isNull(studentFraction)) {
            return AjaxResult.error("当前学生信息不存在！");
        }
        // 根据项目id查询项目的名称
        TestStudentFractionVO studentFractionVO = testItemsMapper.getItemById(itemId);
        String itemName = StringUtils.isBlank(studentFractionVO.getItemName()) ? "" : studentFractionVO.getItemName();
        studentFraction.setItemId(itemId);
        studentFraction.setItemName(itemName);
        studentFraction.setStudentSex(StringUtils.isBlank(studentFraction.getStudentSex()) ? "" : studentFraction.getStudentSex());
        studentFraction.setStudentAge(AgeUtil.getStudentAgeMonth(Objects.isNull(studentFraction.getBirthDate()) ? LocalDate.now().toString() : studentFraction.getBirthDate().toString()));
        //查询test_target_score_fraction 除去身高体重的所有信息得分
        List<TestStudentFractionVO> testTargetScoreFraction = testItemScoreMapper.getTestTargetScoreFraction(studentFraction);
        // 查询height_weight_fraction 根据性别 身高分数  体重分数 得出 体重的得分
        List<TestStudentFractionVO> heightWeightFraction = testItemScoreMapper.getHeightWeight(studentFraction);
        // 判断是体重的得分 还是 判断除去身高体重的所有信息得分
        if (WEIGHT_NAME.equals(itemName)) {
            if (Objects.isNull(itemScore)) {
                return AjaxResult.error("请先添加身高成绩！");
            }
            TestStudentFractionVO fractionVO = heightWeightFraction.stream().filter(Objects::nonNull)
                    .filter(item -> Objects.nonNull(item.getHeightStartValue()) || Objects.nonNull(item.getHeightEndValue())
                            || Objects.nonNull(item.getWeightStartValue()) || Objects.nonNull(item.getWeightEndValue()))
                    .filter(item -> studentFraction.getStudentSex().equals(item.getSex())
                            && (itemScore.compareTo(item.getHeightStartValue()) >= 0 && itemScore.compareTo(item.getHeightEndValue()) <= 0)
                            && (hwfFraction.compareTo(item.getWeightStartValue()) >= 0 && hwfFraction.compareTo(item.getWeightEndValue()) <= 0))
                    .findFirst().orElseGet(TestStudentFractionVO::new);
            if (Objects.nonNull(fractionVO.getHwfFraction())) {
                studentFraction.setFraction(fractionVO.getHwfFraction());
            }
        } else {
            if (Objects.isNull(itemScore)) {
                return AjaxResult.error("请先添加成绩！");
            }
            // 判断除去身高体重的所有信息得分 得到的分数
            TestStudentFractionVO fractionVO = testTargetScoreFraction.stream().filter(Objects::nonNull)
                    .filter(item -> StringUtils.isNotBlank(item.getTestTargetName())
                            || StringUtils.isNotBlank(item.getSex()) || Objects.nonNull(item.getAge())
                            || Objects.nonNull(item.getScoreStartValue()) || Objects.nonNull(item.getScoreEndValue()))
                    .filter(item -> itemName.equals(item.getTestTargetName())
                            && studentFraction.getStudentSex().equals(item.getSex())
                            && studentFraction.getStudentAge().equals(item.getAge())
                            && (itemScore.compareTo(item.getScoreStartValue()) >= 0 && itemScore.compareTo(item.getScoreEndValue()) <= 0))
                    .findFirst().orElseGet(TestStudentFractionVO::new);
            if (Objects.nonNull(fractionVO.getFraction())) {
                studentFraction.setFraction(fractionVO.getFraction());
            }
        }
        return AjaxResult.success(studentFraction);
    }

    /**
     * 导入个人成绩的信息
     *
     * @param list 成绩信息
     * @return AjaxResult
     */
    @Override
    public AjaxResult importData(List<ImportTestProjectScoresDTO> list) {
        if (CollectionUtils.isEmpty(list)) {
            return AjaxResult.error("请添加成绩信息数据！");
        }
        //导入幼儿园数据是否唯一校验
        List<String> importKindergartenNameCollect = list.stream().filter(Objects::nonNull).map(ImportTestProjectScoresDTO::getKindergartenName).filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
        if (importKindergartenNameCollect.size() != 1) {
            return AjaxResult.error("幼儿园名称不唯一，请检查后重新录入！");
        }
        //导入批次数据是否唯一校验
        List<String> importBatchCodeCollect = list.stream().filter(Objects::nonNull).map(ImportTestProjectScoresDTO::getBatchCode).filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
        if (importBatchCodeCollect.size() != 1) {
            return AjaxResult.error("批次编号不唯一，只能录入同批次的成绩！");
        }
        //导入学生数据是否为空校验
        List<String> importItemStudentNumber = list.stream().filter(Objects::nonNull).map(ImportTestProjectScoresDTO::getStudentNumber).filter(StringUtils::isNotBlank).collect(Collectors.toList());
        if (importItemStudentNumber.stream().distinct().count() < 1) {
            return AjaxResult.error("请录入学生信息！");
        }
        //导入数据根据学生编号和项目编号校验唯一数据 repeatTestProjectScoreList 返回冲数据集合
        List<ImportTestProjectScoresDTO> repeatTestProjectScoreList = new ArrayList<>();
        List<ImportTestProjectScoresDTO> distinctClass = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(item ->
                item.getStudentNumber() + ";" + item.getItemCode()))), ArrayList::new));
        if (list.size() != distinctClass.size()) {
            list.removeAll(distinctClass);
            repeatTestProjectScoreList.addAll(list);
            list = distinctClass;
        }
        //数据库查询幼儿园信息，校验幼儿园名称
        Long kindergartenId = kindergartenInfoMapper.getKindergartenByKindergartenName(importKindergartenNameCollect.get(0));
        if (Objects.isNull(kindergartenId)) {
            return AjaxResult.error("幼儿园不存在，请检查后重新录入！");
        }
        //班级名称校验
        List<ClassInfo> classList = classInfoMapper.getClassList(kindergartenId, null);
        List<String> classNameCollect = classList.stream().filter(Objects::nonNull).map(ClassInfo::getClassName).filter(StringUtils::isNotBlank).collect(Collectors.toList());
        List<String> importClassNameCollect = list.stream().filter(Objects::nonNull).map(ImportTestProjectScoresDTO::getClassName).filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
        Collection<String> subtractClassName = CollectionUtils.subtract(importClassNameCollect, classNameCollect);
        if (CollectionUtils.isNotEmpty(subtractClassName)) {
            StringBuilder className = new StringBuilder();
            for (String name : subtractClassName) {
                className.append(name).append(" ");
            }
            return AjaxResult.error("该班级名称:" + className + "不属于本幼儿园，请检查数据后重新录入！");
        }
        //学生所属幼儿园及班级校验
        List<StudentInfo> studentInfos = testItemScoreMapper.selectStudentIdByKindergartenId(kindergartenId);
        List<String> collect = studentInfos.stream().filter(Objects::nonNull).map(StudentInfo::getStudentNumber).filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
        List<String> importDistinctStudentNumber = importItemStudentNumber.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());
        Collection<String> studentNumberSubtract = CollectionUtils.subtract(importDistinctStudentNumber, collect);
        if (CollectionUtils.isNotEmpty(studentNumberSubtract)) {
            StringBuilder studentNumber = new StringBuilder();
            for (String number : studentNumberSubtract) {
                studentNumber.append(number).append(" ");
            }
            return AjaxResult.error("该学生编号:" + studentNumber + "不属于本幼儿园！");
        }
        //校验项目是否是该批次
        List<ItemStudentScoreDTO> testBatchItemInfoList = testItemScoreMapper.getTestBatchItemInfoList(importBatchCodeCollect.get(0));
        List<String> itemCodeCollect = testBatchItemInfoList.stream().filter(Objects::nonNull).map(ItemStudentScoreDTO::getItemCode).filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
        List<String> importItemCodeCollect = list.stream().filter(Objects::nonNull).map(ImportTestProjectScoresDTO::getItemCode).filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList());
        Collection<String> subtract = CollectionUtils.subtract(importItemCodeCollect, itemCodeCollect);
        if (CollectionUtils.isNotEmpty(subtract)) {
            StringBuilder itemCode = new StringBuilder();
            for (String code : subtract) {
                itemCode.append(code).append(" ");
            }
            return AjaxResult.error("该项目编号:" + itemCode + "不属于本批次的项目，请检查数据后重新录入！");
        }
        //校验是否与数据库数据存在重复
        List<ImportTestProjectScoresDTO> testProjectScoreList = new ArrayList<>();
        List<Long> studentIds = studentInfos.stream().filter(Objects::nonNull).map(StudentInfo::getId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<ImportTestProjectScoresDTO> testItemScores = testItemScoreMapper.selectTestItemScore(importBatchCodeCollect.get(0),studentIds);
        for (ImportTestProjectScoresDTO importTestProjectScores : list) {
            StudentInfo studentInfo = studentInfos.stream().filter(Objects::nonNull).filter(item -> StringUtils.isNotBlank(item.getStudentNumber()) && importTestProjectScores.getStudentNumber().equals(item.getStudentNumber())).findFirst().orElseGet(StudentInfo::new);
            importTestProjectScores.setClassId(studentInfo.getClassId());
            importTestProjectScores.setStudentId(studentInfo.getId());
            ImportTestProjectScoresDTO testProjectScores = testItemScores.stream().filter(Objects::nonNull).filter(item -> Objects.nonNull(item.getStudentId()) && StringUtils.isNotBlank(item.getItemCode()) && importTestProjectScores.getStudentId().equals(item.getStudentId()) && importTestProjectScores.getItemCode().equals(item.getItemCode())).findFirst().orElseGet(ImportTestProjectScoresDTO::new);
            if (Objects.nonNull(testProjectScores.getItemCode())) {
                repeatTestProjectScoreList.add(importTestProjectScores);
                continue;
            }
            ItemStudentScoreDTO itemStudentScore = testBatchItemInfoList.stream().filter(Objects::nonNull).filter(item -> StringUtils.isNotBlank(item.getItemCode()) && importTestProjectScores.getItemCode().equals(item.getItemCode())).findFirst().orElseGet(ItemStudentScoreDTO::new);
            importTestProjectScores.setTestItemId(itemStudentScore.getTestItemId());
            importTestProjectScores.setUserId(SecurityUtils.getUserId());
            importTestProjectScores.setKindergartenId(kindergartenId);
            importTestProjectScores.setScoreDictId(itemStudentScore.getScoreDictId());
            importTestProjectScores.setCreateTime(DateUtils.getNowDate());
            importTestProjectScores.setCreateBy(SecurityUtils.getUsername());
            importTestProjectScores.setDelFlag(0);
            testProjectScoreList.add(importTestProjectScores);
        }
        if (CollectionUtils.isNotEmpty(testProjectScoreList)) {
            int insertCount = testItemScoreMapper.importTestItemScoreList(testProjectScoreList);
            if (insertCount <= 0) {
                throw new ServiceException("导入测试项目个人成绩信息失败");
            }
        }
        if (CollectionUtils.isNotEmpty(repeatTestProjectScoreList)) {
            return AjaxResult.error("录入完成,重复数据", repeatTestProjectScoreList);
        }
        return AjaxResult.success("录入完成");
    }

    /**
     * 分页查询个人成绩列表信息
     *
     * @param testItemScore 输入参数
     * @return 成绩列表信息
     */
    private TableDataInfo getTestItemInfoList(TestItemScoreinfoVO testItemScore) {
        pageServiceUtil.startPage();
        List<TestItemScoreUpdateVO> studentInfoList = testItemScoreMapper.selectTestItemScoreList(testItemScore);
        return pageServiceUtil.getDataTable(studentInfoList);
    }

    /**
     * 判断测试成绩是否在最小值和最大值之间
     *
     * @param testItemStandardList 测试项目标准成绩集合
     * @param itemScoreList        项目成绩集合
     * @return 校验结果
     */
    private AjaxResult judgeItemScore(List<TestItemStandard> testItemStandardList, List<ItemStudentScoreDTO> itemScoreList) {
        Map<Long, ItemStudentScoreDTO> itemStudentScoreMap = itemScoreList.stream().filter(item -> Objects.nonNull(item.getTestItemId())).collect(Collectors.toMap(ItemStudentScoreDTO::getTestItemId, item -> item));
        for (TestItemStandard testItemStandard : testItemStandardList) {
            ItemStudentScoreDTO studentScoreDTO = itemStudentScoreMap.getOrDefault(Objects.isNull(testItemStandard.getTestItemsId()) ? 0L : testItemStandard.getTestItemsId(), new ItemStudentScoreDTO());
            if (Objects.isNull(studentScoreDTO)) {
                continue;
            }
            if (Objects.nonNull(testItemStandard.getMinScore()) && Objects.nonNull(testItemStandard.getMaxScore()) &&
                    Objects.nonNull(studentScoreDTO.getItemFraction())) {
                if (!(studentScoreDTO.getItemFraction().compareTo(testItemStandard.getMinScore()) >= 0
                        && studentScoreDTO.getItemFraction().compareTo(testItemStandard.getMaxScore()) <= 0)) {
                    return AjaxResult.error("测试项目得分应该在最小得分和最大得分之间！");
                }
            } else if (Objects.nonNull(testItemStandard.getMinScore()) && Objects.isNull(testItemStandard.getMaxScore()) && Objects.nonNull(studentScoreDTO.getItemScore())) {
                // 如果最小值不为空 最大值为空
                if (studentScoreDTO.getItemFraction().compareTo(testItemStandard.getMinScore()) < 0) {
                    return AjaxResult.error("测试项目得分不能小于项目最低得分！");
                }
            } else if (Objects.isNull(testItemStandard.getMinScore()) && Objects.nonNull(testItemStandard.getMaxScore()) && Objects.nonNull(studentScoreDTO.getItemScore())) {
                // 如果最大值不为空 最小值为空
                if (studentScoreDTO.getItemFraction().compareTo(testItemStandard.getMaxScore()) > 0) {
                    return AjaxResult.error("测试项目得分不能大于项目最高得分！");
                }
            }
        }
        return null;
    }

    /**
     * 设置新增测试项目成绩信息
     *
     * @param testItemScore 输入参数
     * @return 个人信息集合
     */
    private List<TestItemScore> setCreateTestItemScoreInfo(TestItemScoreInfoUpdateDTO testItemScore) {
        List<TestItemScore> testItemScoreList = Lists.newArrayList();
        for (ItemStudentScoreDTO dto : testItemScore.getItemScoreList()) {
            TestItemScore testItemScoreInfo = new TestItemScore();
            testItemScoreInfo.setUserId(SecurityUtils.getUserId());
            testItemScoreInfo.setClassId(testItemScore.getClassId());
            testItemScoreInfo.setStudentId(testItemScore.getStudentId());
            testItemScoreInfo.setTestItemId(dto.getTestItemId());
            testItemScoreInfo.setScoreDictId(dto.getScoreDictId());
            testItemScoreInfo.setScoreDictValue(StringUtils.isBlank(dto.getScoreDictValue()) ? "" : dto.getScoreDictValue());
            testItemScoreInfo.setBatchCode(testItemScore.getBatchCode());
            testItemScoreInfo.setItemScore(Objects.isNull(dto.getItemScore()) ? null : dto.getItemScore());
            testItemScoreInfo.setItemFraction(Objects.isNull(dto.getItemFraction()) ? null : dto.getItemFraction());
            testItemScoreInfo.setSyntheticalAssess(StringUtils.isBlank(dto.getSyntheticalAssess()) ? "" : dto.getSyntheticalAssess());
            testItemScoreInfo.setDelFlag(0);
            testItemScoreInfo.setCreateTime(DateUtils.getNowDate());
            testItemScoreInfo.setCreateBy(testItemScore.getCreateBy());
            testItemScoreList.add(testItemScoreInfo);
        }
        return testItemScoreList;
    }

    /**
     * 设置修改测试项目成绩信息
     *
     * @param testItemScore 输入参数
     */
    private void updateTestItemScoreInfo(TestItemScoreInfoUpdateDTO testItemScore) {
        for (ItemStudentScoreDTO dto : testItemScore.getItemScoreList()) {
            TestItemScore testItemScoreInfo = new TestItemScore();
            if (Objects.isNull(dto.getId())) {
                //新增测试项目成绩信息
                this.buildTestItemScore(testItemScore, testItemScoreInfo, dto);
                testItemScoreInfo.setCreateTime(DateUtils.getNowDate());
                testItemScoreInfo.setCreateBy(testItemScore.getUpdateBy());
                int insertItemScoreCount = testItemScoreMapper.insertTestItemScoreInfo(testItemScoreInfo);
                if (insertItemScoreCount <= 0) {
                    throw new ServiceException("新增测试项目个人成绩信息失败");
                }
            } else {
                //修改原有测试项目成绩信息
                this.buildTestItemScore(testItemScore, testItemScoreInfo, dto);
                testItemScoreInfo.setId(dto.getId());
                testItemScoreInfo.setUpdateTime(DateUtils.getNowDate());
                testItemScoreInfo.setUpdateBy(testItemScore.getUpdateBy());
                int updateCount = testItemScoreMapper.updateTestItemScoreInfo(testItemScoreInfo);
                if (updateCount <= 0) {
                    throw new ServiceException("更新测试项目个人成绩信息失败");
                }
            }
        }
    }

    /**
     * 构建测试项目成绩信息
     *
     * @param testItemScore     页面输入信息
     * @param testItemScoreInfo 当前成绩实体信息
     * @param dto               测试项目成绩信息
     */
    private void buildTestItemScore(TestItemScoreInfoUpdateDTO testItemScore,
                                    TestItemScore testItemScoreInfo, ItemStudentScoreDTO dto) {
        testItemScoreInfo.setUserId(SecurityUtils.getUserId());
        testItemScoreInfo.setClassId(testItemScore.getClassId());
        testItemScoreInfo.setStudentId(testItemScore.getStudentId());
        testItemScoreInfo.setTestItemId(dto.getTestItemId());
        testItemScoreInfo.setScoreDictId(dto.getScoreDictId());
        testItemScoreInfo.setScoreDictValue(StringUtils.isBlank(dto.getScoreDictValue()) ? "" : dto.getScoreDictValue());
        testItemScoreInfo.setBatchCode(testItemScore.getBatchCode());
        testItemScoreInfo.setItemScore(Objects.isNull(dto.getItemScore()) ? null : dto.getItemScore());
        testItemScoreInfo.setItemFraction(Objects.isNull(dto.getItemFraction()) ? null : dto.getItemFraction());
        testItemScoreInfo.setSyntheticalAssess(StringUtils.isBlank(dto.getSyntheticalAssess()) ? "" : dto.getSyntheticalAssess());
        testItemScoreInfo.setDelFlag(0);
    }


}
