package com.yida.data.school.health.service.impl;

import cc.mrbird.febs.common.redis.service.RedisService;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yida.data.common.core.entity.health.*;
import com.yida.data.common.core.entity.health.enums.HealthSourceTypeEnum;
import com.yida.data.common.core.entity.user.EduStudent;
import com.yida.data.school.health.mapper.EduNationalStandardProjectScoreMapper;
import com.yida.data.school.health.mapper.EduStudentPhysicalExaminationGradeResultsMapper;
import com.yida.data.school.health.mapper.EduStudentProjectTestResultMapper;
import com.yida.data.school.health.service.EduGradeService;
import com.yida.data.school.health.service.EduStudentPhysicalExaminationGradeResultsService;
import com.yida.data.school.health.service.EduStudentProjectTestResultService;
import com.yida.data.school.vo.health.*;
import com.yida.data.user.feign.RemoteStudentService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

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

/**
 * 学生单项成绩记录表 Service实现
 *
 * @author ccl
 * @date 2021-09-14 17:16:24
 */
@Service
@RequiredArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class EduStudentProjectTestResultServiceImpl extends ServiceImpl
        <EduStudentProjectTestResultMapper, EduStudentProjectTestResult> implements EduStudentProjectTestResultService {

    private final EduStudentProjectTestResultMapper eduStudentProjectTestResultMapper;
    private final EduStudentPhysicalExaminationGradeResultsService eduStudentPhysicalExaminationGradeResultsService;
    private final EduStudentPhysicalExaminationGradeResultsMapper gradeResultsMapper;

    private final RedisService redisService;

    @Resource
    private EduGradeService eduGradeService;

    @Resource
    private RemoteStudentService remoteStudentService;

    @Resource
    private EduStudentProjectTestResultService eduStudentProjectTestResultService;

    @Resource
    private EduNationalStandardProjectScoreMapper eduNationalStandardProjectScoreMapper;

    @Override
    public void saveStudentSelfTest(EduStuProjectVO stuProjectVO) {

        Long recordGradeId = stuProjectVO.getRecordGradeId();
        Long stuId = stuProjectVO.getStuId();
        Integer stuSex = stuProjectVO.getStuSex();
        //查询学生的基础信息
        EduStudent student = remoteStudentService.getStudentNoPermission(stuId).getData();

        Long schoolId = student.getSchoolId();
        String schoolName = student.getSchoolName();
        String gradeName = student.getGradeName();
        Long gradeId = student.getGradeId();
        Long classId = student.getClassId();
        String className = student.getClassName();
        String stuNumber = student.getStuNumber();


        List<EduStudentProjectTestResult> studentProjectTestResultList = stuProjectVO.getStudentProjectTestResultList();
        studentProjectTestResultList.forEach(eduStudentProjectTestResult -> {
            Long projectId = eduStudentProjectTestResult.getProjectId();
            String projectName = eduStudentProjectTestResult.getProjectName();
            BigDecimal projectResult = new BigDecimal(eduStudentProjectTestResult.getProjectResult());

            EduStudentProjectTestResult build = new EduStudentProjectTestResult();
            build.setClassId(classId);
            build.setClassName(className);
            build.setGradeName(gradeName);
            build.setGradeId(gradeId);
            build.setStudentNum(stuNumber);
            build.setProjectId(projectId);
            build.setProjectName(projectName);
            build.setProjectResult(eduStudentProjectTestResult.getProjectResult());
            build.setRecordGradeId(recordGradeId);
            build.setStudentId(stuId);
            build.setSchoolId(schoolId);
            build.setSchoolName(schoolName);
            build.setSourceType(1);


            //bmi身高和体重
            if (projectId == (1)) {
                BigDecimal height = eduStudentProjectTestResult.getHeight();
                BigDecimal weight = eduStudentProjectTestResult.getWeight();
                //单位m
                BigDecimal height2 = height.multiply(new BigDecimal("0.0001")).multiply(height).setScale(2, BigDecimal.ROUND_HALF_UP);
                //计算BMI保持一位小数(BMI的数值)
                projectResult = weight.divide(height2, 1, BigDecimal.ROUND_HALF_UP);
                build.setWeight(weight);
                build.setHeight(height);
                build.setProjectResult(projectResult.toString());
            }
            //计算获得的分数,传入年级和性别和数值和项目id计算该项的得分
            //查询BMI的得分(sql去查询)
            EduNationalStandardProjectScore eduNationalStandardProjectScore = new EduNationalStandardProjectScore();
            eduNationalStandardProjectScore.setRecordGradeId(recordGradeId);
            eduNationalStandardProjectScore.setApplySex(stuSex);
            eduNationalStandardProjectScore.setProjectId(projectId);
            eduNationalStandardProjectScore.setResult(projectResult);


            EduNationalStandardProjectScore projectScore = eduNationalStandardProjectScoreMapper.findScoreBySexAndGradeIdAndProjectIdAndResult(new EduNationalStandardProjectScore());
            //单项得分
            Integer score1 = projectScore.getScore();
            //单项得分的等级
            String rank = projectScore.getRank();


            build.setProjectScore(new BigDecimal(score1));
            build.setProjectRank(rank);

            if (projectResult != null) {
                //保存该条数据
                save(build);
            }

        });
    }

    @Override
    public List<EduProjectVO> findStuSelfTestProjectList(String stuSex, Long recordGradeId, Long id) {
        return baseMapper.findStuSelfTestProjectList(stuSex, recordGradeId);
    }

    /**
     * 查询学年国际自测成绩
     *
     * @param id 成绩主键id
     * @return com.yida.data.health.vo.EduNationalProjectVO
     * @author ZYJ
     * @date 2021/10/29 16:41
     */
    @Override
    public EduNationalProjectVO findStuSelfTest(Long id) {
        return null;
    }

    /**
     * 查询学年体测成绩
     *
     * @param id 成绩id
     * @return com.yida.data.health.vo.EduNationalProjectVO
     * @author ZYJ
     * @date 2021/10/29 15:11
     */
    @Override
    public EduNationalProjectVO findStuNationalTest(Long id) {
        EduNationalProjectVO stuNationalTest = baseMapper.findStuNationalTest(id);
        Optional.ofNullable(stuNationalTest).ifPresent(eduNationalProjectVO -> {
            // 判断加减分项目数量
            stuNationalTest.setAddScoreNum(baseMapper.getAddScoreNum(stuNationalTest.getId()));
            stuNationalTest.setFailNum(baseMapper.getFailNum(stuNationalTest.getId()));
            List<EduStudentProjectTestResult> list = this.eduStudentProjectTestResultService.list(Wrappers.lambdaQuery(new EduStudentProjectTestResult())
                    .eq(EduStudentProjectTestResult::getGradeResultId, eduNationalProjectVO.getId())
                    .eq(EduStudentProjectTestResult::getSourceType, HealthSourceTypeEnum.NATIONAL_TYPE.getSourceType()));
            // 返回的测试项目合集
            List<EduSingleProjectVO> singleProjectVOList =
                    list.stream().map(result -> {
                        EduSingleProjectVO eduSingleProjectVO = new EduSingleProjectVO();
                        BeanUtils.copyProperties(result, eduSingleProjectVO);
                        return eduSingleProjectVO;
                    }).collect(Collectors.toList());
            stuNationalTest.setSingleProjectVOList(singleProjectVOList);
        });
        return stuNationalTest;
    }

    @Override
    public List<EduProjectVO> findStuHistoryResultsList(Long stuId, Long recordGradeId, String stuSex) {
        List<EduProjectVO> eduProjectVOS = baseMapper.findStuSelfTestProjectList(stuSex, recordGradeId);

        eduProjectVOS.forEach(coreProjectDto -> {
            Long projectId = coreProjectDto.getProjectId();
            //学生主键id和项目id查询项目成绩列表数据
            coreProjectDto.setProjectResults(baseMapper.findStuResultsList(projectId, stuId));
        });
        return eduProjectVOS;
    }

    @Override
    public List findStuNationalAndSelfTest(Long studentId) {
        EduStudentNationalVO stuNational = baseMapper.findStuNational(studentId);
        if (Objects.isNull(stuNational)) {
            stuNational = new EduStudentNationalVO();
        }
        EduStudentSelfVO stuSelfTest = baseMapper.findStuSelfTest(studentId);
        if (Objects.isNull(stuSelfTest)) {
            stuSelfTest = new EduStudentSelfVO();
        }

        EyesTestNewVO eyesTestNewVO = new EyesTestNewVO();
        // 左眼
        List<EyeResultVO> leftEyesTest = baseMapper.findLastEyesTest(studentId, 22, 1);
        if (CollectionUtils.isEmpty(leftEyesTest)) {
            eyesTestNewVO.setLeftEye(new EyeResultVO());
        } else {
            eyesTestNewVO.setLeftEye(leftEyesTest.get(0));
        }
        // 右眼
        List<EyeResultVO> rightEyesTest = baseMapper.findLastEyesTest(studentId, 23, 1);
        if (CollectionUtils.isEmpty(rightEyesTest)) {
            eyesTestNewVO.setRightEye(new EyeResultVO());
        } else {
            eyesTestNewVO.setRightEye(rightEyesTest.get(0));
        }
        ArrayList<Object> list = new ArrayList<>();
        list.add(stuNational);
        list.add(stuSelfTest);
        list.add(eyesTestNewVO);
        return list;
    }

    @Override
    public List<EduNationalProjectVO> findPageStuSelfTestProjectList(Long studentId) {

        List<EduNationalProjectVO> pageStuSelfTestProjectList = baseMapper.allRecord(studentId);
        if (CollectionUtil.isEmpty(pageStuSelfTestProjectList)) {
            return new ArrayList<>();
        }
        for (EduNationalProjectVO record : pageStuSelfTestProjectList) {
            record.setSingleProjectVOList(baseMapper.findStudentResult(record.getId()));
        }
        return pageStuSelfTestProjectList;
    }

    @Override
    public IPage<StudentHealthListVO> findPageStudent(Long schoolId, Long groupId,Long gradeId, Long classId, String studentName, Page<EduNationalProjectVO> page,Integer type) {
        //先查学生
        IPage<StudentHealthListVO> pageStudent = baseMapper.findPageStudent(page, schoolId,groupId, gradeId, classId, studentName,type);
        for (StudentHealthListVO student : pageStudent.getRecords()) {
            //查询学生历史成绩
            List<EduStudentPhysicalExaminationGradeResults> eduStudentProjectTestResults = baseMapper.selectStudentList(student.getStudentId());

            student.setProjectVO(eduStudentProjectTestResults.get(0));
        }
        return pageStudent;
    }

    @Override
    public void saveOrUpTestProject(EduProject eduProject) throws Exception {
        EduStudentPhysicalExaminationGradeResults gradeResults = eduProject.getCoreStudentPhysicalExaminationGradeResults();
        EduStudent student = remoteStudentService.getStudentNoPermission(eduProject.getStudentId()).getData();
        if (ObjectUtil.isEmpty(gradeResults)){
            gradeResults = new EduStudentPhysicalExaminationGradeResults();
            eduProject.setCoreStudentPhysicalExaminationGradeResults(gradeResults);
            gradeResults.setRecordGradeId(eduProject.getEduGradeId());
            gradeResults.setStudentSex(Integer.parseInt(eduProject.getSex()));
            gradeResults.setStudentId(eduProject.getStudentId());
        }else {
            gradeResults.setStudentSex(gradeResults.getStudentSex());
        }

        if (ObjectUtil.isEmpty(eduProject.getHeight())) {
            throw new Exception("请输入身高");
        }
        if (ObjectUtil.isEmpty(eduProject.getWight())) {
            throw new Exception("请输入体重");
        }
        Long groupId = eduProject.getCoreStudentPhysicalExaminationGradeResults().getGroupId();
        if(ObjectUtil.isNotEmpty(groupId)) {
            List<EduStudentPhysicalExaminationGradeResults> list = eduStudentPhysicalExaminationGradeResultsService.list(Wrappers.lambdaQuery(new EduStudentPhysicalExaminationGradeResults())
                    .eq(EduStudentPhysicalExaminationGradeResults::getGroupId, groupId)
                    .eq(EduStudentPhysicalExaminationGradeResults::getStudentId, eduProject.getStudentId()));

            if (CollectionUtil.isNotEmpty(list) && eduProject.getCoreStudentPhysicalExaminationGradeResults().getId() == null) {
                throw new Exception("提示 ： 本次体侧含有此学生，请选择修改或删除");
            }
        }
        gradeResults.setStudentName(student.getStuName());
        gradeResults.setStudentNumber(student.getStuNumber());
        gradeResults.setSchoolName(student.getSchoolName());
        gradeResults.setSchoolId(student.getSchoolId());
        gradeResults.setClassId(student.getClassId());
        gradeResults.setClassName(student.getClassName());
        gradeResults.setGradeName(student.getGradeName());
        gradeResults.setGradeId(student.getGradeId());


        EduGrade coreGrade = new EduGrade();

        if(ObjectUtil.isEmpty(gradeResults.getRecordGradeName())){
            coreGrade = eduGradeService.getOne(Wrappers.lambdaQuery(new EduGrade())
                    .eq(EduGrade::getId, gradeResults.getRecordGradeId()));
        }else {
            coreGrade = eduGradeService.getOne(Wrappers.lambdaQuery(new EduGrade())
                    .eq(EduGrade::getGradeName, gradeResults.getRecordGradeName()));
        }

        gradeResults.setRecordGradeId(coreGrade.getId());
        eduProject.setEduGradeId(coreGrade.getId());
        if (gradeResults.getStudentSex() == 0) {
            eduProject.setSex("男");
        }
        if (gradeResults.getStudentSex() == 1) {
            eduProject.setSex("女");
        }
        eduStudentPhysicalExaminationGradeResultsService.saveOrUpdate(gradeResults);
        eduStudentPhysicalExaminationGradeResultsService.saveTestResult(eduProject);
    }

    @Override
    public List<SelfHealthVO> findStuHistoryResults(Long studentId, Integer num) {

        //只取最近num次的数据
        List<SelfHealthVO> selfHealthVOS = new ArrayList<>();


        List<HealthHistoryScore> weight = new ArrayList<>();
        List<HealthHistoryScore> height = new ArrayList<>();

        List<EduSingleProjectVO> list = eduStudentProjectTestResultMapper.findAllResult(studentId);
        Map<String, List<EduSingleProjectVO>> groupBy =
                list.stream().collect(Collectors.groupingBy(EduSingleProjectVO::getProjectName));
        //分组再分别封装
        for (List<EduSingleProjectVO> value : groupBy.values()) {
            List<HealthHistoryScore> historyScores = new ArrayList<>();
            if(value.get(0).getCode()==1){
                continue;
            }
            SelfHealthVO selfHealthVO = new SelfHealthVO();
            selfHealthVO.setProjectName(value.get(0).getProjectName());
            selfHealthVO.setProjectResult(value.get(0).getProjectResult());
            if (ObjectUtil.isNotEmpty(value.get(0).getProjectScore()) && value.size() > 1 && ObjectUtil.isNotEmpty(value.get(1).getProjectScore())) {
                selfHealthVO.setAddNum(value.get(0).getProjectScore().subtract(value.get(1).getProjectScore()).toString());
            } else if (value.size() == 1) {
                selfHealthVO.setAddNum("0");
            } else {
                selfHealthVO.setAddNum("0");
            }
            selfHealthVO.setProjectRank(value.get(0).getProjectRank());
            selfHealthVO.setCode(value.get(0).getCode());
            selfHealthVO.setUpdateTime(value.get(0).getCreateDate());

            for (int i = 0; i < value.size(); i++) {
                if (i == num) {
                    break;
                }
                HealthHistoryScore healthHistoryScore = new HealthHistoryScore();
                healthHistoryScore.setCreateDate(value.get(i).getCreateDate());
                //当结果为跑步时用分数来做结果
                if (value.get(i).getProjectId() == 14 ||value.get(i).getProjectId() == 20 ||value.get(i).getProjectId() ==21){
                    healthHistoryScore.setResult(value.get(i).getProjectScore().toString());
                }else {
                    healthHistoryScore.setResult(value.get(i).getProjectResult());
                }

                historyScores.add(healthHistoryScore);
            }
            selfHealthVO.setHistoryScore(CollectionUtil.reverse(historyScores));
            selfHealthVOS.add(selfHealthVO);
        }
        SelfHealthVO selfHealthVO1 = new SelfHealthVO();
        SelfHealthVO selfHealthVO2 = new SelfHealthVO();
        selfHealthVO1.setCode(50);

        selfHealthVO2.setCode(100);
        selfHealthVO1.setProjectName("体重");
        selfHealthVO2.setProjectName("身高");

        List<EduSingleProjectVO> BMI = groupBy.get("体重指数（BMI）");
        if (CollectionUtil.isEmpty(BMI)){
            selfHealthVO1.setAddNum("0");
            selfHealthVO2.setAddNum("0");
            selfHealthVO1.setHistoryScore(weight);
            selfHealthVO2.setHistoryScore(height);
            selfHealthVOS.add(selfHealthVO1);
            selfHealthVOS.add(selfHealthVO2);
            return selfHealthVOS;
        }
        for (int i = 0; i <BMI.size() ; i++) {
            if (i==num){
                break;
            }
            HealthHistoryScore healthHistoryScore = new HealthHistoryScore();
            healthHistoryScore.setResult(BMI.get(i).getWeight().toString());
            healthHistoryScore.setCreateDate(BMI.get(i).getCreateDate());
            weight.add(healthHistoryScore);

            HealthHistoryScore healthHistoryScore1 = new HealthHistoryScore();
            healthHistoryScore1.setResult(BMI.get(i).getHeight().toString());
            healthHistoryScore1.setCreateDate(BMI.get(i).getCreateDate());
            height.add(healthHistoryScore1);
        }
        if (BMI.size()>=2){
            selfHealthVO1.setAddNum(BMI.get(0).getWeight().subtract(BMI.get(1).getWeight()).toString());
            selfHealthVO2.setAddNum(BMI.get(0).getHeight().subtract(BMI.get(1).getHeight()).toString());
        }

        if (ObjectUtil.isNotEmpty(BMI.get(0).getProjectResult())){
            selfHealthVO1.setProjectResult(BMI.get(0).getWeight().toString());
            selfHealthVO1.setUpdateTime(BMI.get(0).getCreateDate());
            selfHealthVO2.setProjectResult(BMI.get(0).getHeight().toString());
            selfHealthVO2.setUpdateTime(BMI.get(0).getCreateDate());
        }else {
            selfHealthVO1.setProjectResult(null);
            selfHealthVO2.setProjectResult(null);
        }
        if (ObjectUtil.isNotEmpty(BMI.get(0).getProjectRank())){
            selfHealthVO1.setProjectRank(BMI.get(0).getProjectRank());
            selfHealthVO2.setProjectRank(BMI.get(0).getProjectRank());
        }else {
            selfHealthVO1.setUpdateTime(null);
            selfHealthVO2.setUpdateTime(null);
        }
        selfHealthVO1.setHistoryScore(CollectionUtil.reverse(weight));
        selfHealthVO2.setHistoryScore(CollectionUtil.reverse(height));
        selfHealthVOS.add(selfHealthVO1);
        selfHealthVOS.add(selfHealthVO2);
        return selfHealthVOS;

    }

    /**
     * 查询最新一次的成绩
     *
     * @param studentId
     * @return
     */
    @Override
    public NationalHealthVO findLastResults(Long studentId) {

        NationalHealthVO nationalHealthVO = new NationalHealthVO();

        EduStudent data = remoteStudentService.getStudentNoPermission(studentId).getData();
        if (ObjectUtil.isNotEmpty(data)){
            nationalHealthVO.setEduStudent(data);
        }

        //筛除未发布的数据
        List<EduStudentPhysicalExaminationGradeResults> nationalResult = gradeResultsMapper.findLastResults(studentId);

        if (CollectionUtil.isNotEmpty(nationalResult)) {
            EduStudentPhysicalExaminationGradeResults gradeResult = nationalResult.get(0);

            List<EduSingleProjectVO> list = eduStudentProjectTestResultMapper.findAllTest(gradeResult.getId());

            nationalHealthVO.setTotalScore(gradeResult.getTotalScore());
            nationalHealthVO.setEduSingleProjectVO(list);
            nationalHealthVO.setProjectRank(gradeResult.getTotalRank());
            nationalHealthVO.setCreateDate(gradeResult.getCreateDate());

            int add = 0;
            int fail = 0;

            for (EduSingleProjectVO eduSingleProjectVO : list) {
                if (ObjectUtil.isNotEmpty(eduSingleProjectVO.getProjectExtraScore())) {
                    if (eduSingleProjectVO.getProjectExtraScore().compareTo(new BigDecimal("0")) == 1) {
                        add++;
                    }
                }

                if ("不及格".equals(eduSingleProjectVO.getProjectRank())) {
                    fail++;
                }

            }
            nationalHealthVO.setAddNum(add);
            nationalHealthVO.setFailNum(fail);
            return nationalHealthVO;
        }
        return nationalHealthVO;
    }

    @Override
    public List<AppHistoryHealthVO> findStudentHistoryResults(Long studentId) {

        List<AppHistoryHealthVO> historyHealth = new ArrayList<>();
        List<AppHistoryHealthVO> historyHealthVO = baseMapper.findStudentHistoryResults(studentId);
        Map<String, List<AppHistoryHealthVO>> resultList = historyHealthVO.stream().collect(Collectors.groupingBy(AppHistoryHealthVO::getProjectName));
        for (List<AppHistoryHealthVO> value : resultList.values()) {

            AppHistoryHealthVO history = value.get(0);
            value.remove(0);
            history.setHistoryHealthVO(value);
            historyHealth.add(history);
        }
        return historyHealth;
    }

    @Override
    public EyesTestVO findLastEyesTest(Long studentId,Integer num) {
        EyesTestVO eyesTestVO = new EyesTestVO();
        List<EyeResultVO> eyesTest = baseMapper.findEyesTest(studentId, 22);

        if (eyesTest.size()>num){
            eyesTestVO.setLeftEye(CollectionUtil.reverse(eyesTest.subList(0, num-1)));
            eyesTestVO.setRightEye(CollectionUtil.reverse(baseMapper.findEyesTest(studentId,23).subList(0,num-1)));
            return eyesTestVO;
        }else if(CollectionUtil.isEmpty(eyesTest)){
            return eyesTestVO;
        }
        eyesTestVO.setLeftEye(CollectionUtil.reverse(eyesTest.subList(0, eyesTest.size()-1)));
        eyesTestVO.setRightEye(CollectionUtil.reverse(baseMapper.findEyesTest(studentId,23).subList(0,eyesTest.size()-1)));
        return eyesTestVO;
    }

    @Override
    public void removeTestProject(Long gradeResultId) {
        eduStudentPhysicalExaminationGradeResultsService.removeById(gradeResultId);
        remove(Wrappers.lambdaQuery(new EduStudentProjectTestResult())
                .eq(EduStudentProjectTestResult::getGradeResultId, gradeResultId));
    }

    @Override
    public EduNationalProjectVO findOneStuSelfTestProject(Long gradeResultId) {

        EduNationalProjectVO eduNationalProjectVO = baseMapper.findOneStuSelfTestProject(gradeResultId);
        List<EduSingleProjectVO> list = eduStudentProjectTestResultMapper.findAllTest(gradeResultId);
        eduNationalProjectVO.setSingleProjectVOList(list);

        return  eduNationalProjectVO;
    }
}
