package com.xhkjedu.sexam.service.report;

import com.alibaba.fastjson.JSON;
import com.xhkjedu.sexam.mapper.exam.EBaseMapper;
import com.xhkjedu.sexam.mapper.exam.EClassMapper;
import com.xhkjedu.sexam.mapper.report.ERbaseMapper;
import com.xhkjedu.sexam.mapper.report.EReportSchoolMapper;
import com.xhkjedu.sexam.mapper.report.ERsubjectMapper;
import com.xhkjedu.sexam.mapper.reportclass.ERclassMapper;
import com.xhkjedu.sexam.mapper.reportclass.ERclassRankMapper;
import com.xhkjedu.sexam.mapper.reportstu.ERstudentMapper;
import com.xhkjedu.sexam.model.exam.EBase;
import com.xhkjedu.sexam.model.reportstu.ERstudent;
import com.xhkjedu.sexam.model.reportstu.ERstudentAction;
import com.xhkjedu.sexam.utils.ExamUtil;
import com.xhkjedu.sexam.vo.report.ERankParamVo;
import com.xhkjedu.utils.N_Utils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author ywx
 * @className EReportSchoolService
 * @description 校级报告
 * @date 2022/8/8 9:46
 **/
@Service
public class EReportSchoolService {
    @Resource
    private ERbaseMapper eRbaseMapper;
    @Resource
    private ERsubjectMapper eRsubjectMapper;
    @Resource
    private ERstudentMapper eRstudentMapper;
    @Resource
    private ERclassMapper eRclassMapper;
    @Resource
    private ERclassRankMapper eRclassRankMapper;
    @Resource
    private EReportGenerateService eReportGenerateService;
    @Resource
    private EReportSchoolMapper eReportSchoolMapper;
    @Resource
    private EBaseMapper eBaseMapper;
    @Resource
    private EClassMapper eClassMapper;

    //考试概况
    public Map getKsGk(Integer examid) {
        Map map = eRbaseMapper.findByExamId(examid);
        //成绩概况
        List<Map> subjects = eRsubjectMapper.listByExamId(examid);
        map.put("subjects", subjects);
        return map;
    }

    //成绩单
    public List<Map> listCjd(ERstudent stu) {
        return eRstudentMapper.listByExamId(stu);
    }

    //成绩分析-班级成绩
    public List<Map> listCjFxBjCj(ERankParamVo rank) {
        return eRclassMapper.listByExamId(rank);
    }

    //成绩分析-等级统计搜索
    public Map listCjFxForSearch(ERankParamVo rank) {
        Map map = eRclassRankMapper.getRank(rank);
        List<Map> ranks = eRclassRankMapper.listByExamId(rank);
        Integer ranktype = rank.getRanktype();
        setClassRank(map, ranks, ranktype);//处理班级报告等级分布数据
        return map;
    }

    //处理班级报告等级分布数据
    private void setClassRank(Map map, List<Map> ranks, Integer ranktype) {
        if (map == null) map = new HashMap();
        if (1 == ranktype) {//等级
            Map<Object, List<Map>> collect = ranks.stream().collect(Collectors.groupingBy(r -> r.get("rankname"),
                    LinkedHashMap::new, Collectors.toList()));
            for (Map.Entry<Object, List<Map>> entry : collect.entrySet()) {
                Integer znum = 0;//范围内总人数
                List<Map> rankList = entry.getValue();
                for (int i = 0; i < rankList.size(); i++) {
                    Map r = rankList.get(i);
                    if (i == 0) {
                        r.put("rsturate", 100.0);//等级占比=班级A类人数/全年级A类人数
                        znum = (Integer) r.get("stunum");
                    } else {
                        r.put("rsturate", N_Utils.getIntegerDivideAndMulitiply((Integer) r.get("stunum"), znum));
                    }
                }
            }
        } else if (3 == ranktype) {//临界分
            Double linescore = Double.valueOf(ExamUtil.removeStrEnd0(map.get("linescore")));//临界分值
            for (Map r : ranks) {
                List<Map> students = JSON.parseArray(r.get("stujson").toString(), Map.class);
                long dynum = students.stream().filter(s -> (Double.valueOf(s.get("score").toString()))
                        .compareTo(linescore) == 1).count();
                long xynum = students.stream().filter(s -> (Double.valueOf(s.get("score").toString()))
                        .compareTo(linescore) != 1).count();
                r.put("dynum", dynum);//大于临界分人数
                r.put("xynum", xynum);//小于等于临界分人数
                r.remove("stujson");
            }
        } else if (4 == ranktype) {//临界名次
            Double linescore = Double.valueOf(ExamUtil.removeStrEnd0(map.get("linescore")));//临界名次
            for (Map r : ranks) {
                List<Map> students = JSON.parseArray(r.get("stujson").toString(), Map.class);
                long dynum = students.stream().filter(s -> (Double.valueOf(s.get("schoolrank").toString()))
                        .compareTo(linescore) == 1).count();
                long xynum = students.stream().filter(s -> (Double.valueOf(s.get("schoolrank").toString()))
                        .compareTo(linescore) != 1).count();
                r.put("dynum", dynum);//大于临界名次人数
                r.put("xynum", xynum);//小于等于临界名次人数
                r.remove("stujson");
            }
        }
        map.put("ranks", ranks);
    }

    //成绩分析-等级统计设置
    @Transactional(rollbackFor = Exception.class)
    public void listCjFxForSet(ERankParamVo rank) {
        Integer examid = rank.getExamid();
        String subjectid = rank.getSubjectid();
        Integer createid = rank.getCreateid();
        Integer ranktype = rank.getRanktype();
        eReportSchoolMapper.delByExamAndSubjectId(examid, subjectid, ranktype);//删除考试等级报告
        eReportGenerateService.setSubjectRank(examid, subjectid, createid, rank.getRranks(), ranktype);//生成考试等级报告
    }

    //行为分析-班级
    public List<Map> listXwBj(ERstudentAction rank) {
        return eReportSchoolMapper.listXwBj(rank);
    }

    //行为分析-学生
    public List<Map> listXwXs(ERstudentAction rank) {
        return eReportSchoolMapper.listXwXs(rank);
    }

    //违纪行为分析-详情
    public List<Map> listWjXq(ERstudentAction rank) {
        return eReportSchoolMapper.listWjXq(rank);
    }

    //等级分类列表
    public List<Map> listDjFl(ERankParamVo rank) {
        return eReportSchoolMapper.listDjFl(rank);
    }

    //校级报告--已结束考试列表
    public List<Map> listEndExams(EBase eBase) {
        return eReportSchoolMapper.listEndExams(eBase);
    }

    //行为分析-班级
    public List<Map> listXwBjByExamId(Integer examid) {
        return eReportSchoolMapper.listXwBjByExamId(examid);
    }

    //考试班级等级分析
    public List<Map> listCjFxByExamId(Integer examid) {
        List<Map> ranks = eReportSchoolMapper.listRankByExamId(examid);
        List<Map> list = eReportSchoolMapper.listCjFxByExamId(examid);
        for (Map map : ranks) {
            Integer ranktype = (Integer) map.get("ranktype");
            Object subjectid = map.get("subjectid");
            List<Map> list2 = list.stream().filter(l -> l.get("ranktype").equals(ranktype)
                    && l.get("subjectid").equals(subjectid)).collect(Collectors.toList());
            setClassRank(map, list2, ranktype);
        }
        return ranks;
    }

    //pdf考试概况
    public Map getPdfKsGk(Integer examid) {
        Map map = eRbaseMapper.findByExamId(examid);
        //成绩概况
        List<Map> subjects = eRsubjectMapper.listByExamId(examid);
        map.put("subjects", subjects);
        map.put("stunum", (Integer) map.get("stunum") - (Integer) map.get("missnum"));
        Map base = eBaseMapper.findById2(examid);
        map.putAll(base);
        Map zfmap = subjects.stream().filter(s -> s.get("subjectid").toString().equals("zf")).findFirst().orElse(null);
        if(zfmap !=null){
            map.put("allscore", ExamUtil.removeStrEnd0(zfmap.get("score")));//满分
        }else{
            double allscore = subjects.stream().mapToDouble(s -> Double.valueOf(ExamUtil.removeStrEnd0(s.get("score")))).sum();
            map.put("allscore", allscore);//满分
        }

        return map;
    }

    //获取考试基本信息（科目、班级）
    public Map getExamSubjectClass(Integer examid) {
        Map map = eBaseMapper.findById(examid);
        List<Map> subjects = eRsubjectMapper.listByExamIdForSel(examid);
        map.put("subjects", subjects);
        List<Map> classes = eClassMapper.listByExamId(examid);
        map.put("classes",classes);
        return map;
    }

    //获取教师显示排名得分
    public Integer getShowRank(Integer examid) {
        EBase base = eBaseMapper.getShowRankById(examid);
        return base.getTeashowrank();
    }

    //根据考试id获取pdf报告状态和校级报告地址
    public Map getReportSchool(Integer examid){
        return eBaseMapper.getReportSchool(examid);
    }

    //获取考试PDF报告基础信息
    public Map getPdfInfo(Integer examid) {
        return eReportSchoolMapper.getPdfInfo(examid);
    }
}
