package com.xhkjedu.sapi.service.region;

import com.xhkjedu.sapi.mapper.region.RegionAnalyzeMapper;
import com.xhkjedu.utils.N_Utils;
import com.xhkjedu.sapi.vo.region.*;
import org.springframework.stereotype.Service;

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

/**
 * @author ywx
 * @className RegionAnalyzeService
 * @description
 * @date 2021/5/13 15:11
 **/
@Service
public class RegionAnalyzeService {
    @Resource
    private RegionAnalyzeMapper regionAnalyzeMapper;

    //获取区平台信息
    public CloudVo getCloudInfo() {
        return regionAnalyzeMapper.getCloudInfo();
    }

    //获取资源、试题总量
    public Map getResourceQuestionNum() {
        return regionAnalyzeMapper.getResourceQuestionNum();
    }

    //获取资源类型统计
    public Map listResourceTypeNum() {
        Map map = new HashMap();

        List<ResourceTypeVo> lst = regionAnalyzeMapper.listResourceTypeNum();
        List<Map> levelsmap = new ArrayList<>();
        Integer totalnum = 0;

        if (lst != null && lst.size() > 0) {
            totalnum = lst.stream().mapToInt(ResourceTypeVo::getRnum).sum();

            for (ResourceTypeVo r : lst) {
                //学段
                if (!isExistLeves(r.getLevel(), levelsmap)) {

                    //学段下所有类型集合
                    List<ResourceTypeVo> stypes = lst.stream().filter(resourceTypeVo -> resourceTypeVo.getLevel().equals(r.getLevel())).collect(Collectors.toList());
                    Integer levelnum = stypes.stream().mapToInt(ResourceTypeVo::getRnum).sum();
                    double levelrate = N_Utils.getIntegerDivideAndMulitiply(levelnum, totalnum);

                    ResourceTypeVo maxtype = stypes.stream().max(Comparator.comparing(ResourceTypeVo::getRnum)).get();//最高的类型
                    double maxtyperate = N_Utils.getIntegerDivideAndMulitiply(maxtype.getRnum(), levelnum);

                    //处理平台资源和校本资源
                    Integer ptnum = stypes.stream().mapToInt(ResourceTypeVo::getPtnum).sum();
                    Integer xbnum = stypes.stream().mapToInt(ResourceTypeVo::getXbnum).sum();
                    double ptrate = N_Utils.getIntegerDivideAndMulitiply(ptnum, levelnum);
                    double xbrate = N_Utils.getIntegerDivideAndMulitiply(xbnum, levelnum);

                    List<Map> tmlst = new ArrayList<>();
                    for(ResourceTypeVo rt : stypes){
                        Map tmap = new HashMap();
                        double srate = N_Utils.getIntegerDivideAndMulitiply(rt.getRnum(),levelnum);
                        tmap.put("rtype",rt.getRtype());
                        tmap.put("rnum",rt.getRnum());
                        tmap.put("rrate",srate);

                        tmlst.add(tmap);
                    }

                    Map lmap = new HashMap();
                    lmap.put("level", r.getLevel());
                    lmap.put("levelnum", levelnum);
                    lmap.put("levelrate", levelrate);
                    lmap.put("rtypes", tmlst);//类型
                    lmap.put("maxtype", maxtype.getRtype());
                    lmap.put("maxnum", maxtype.getRnum());
                    lmap.put("maxrate", maxtyperate);
                    lmap.put("ptrate", ptrate);
                    lmap.put("xbrate", xbrate);
                    levelsmap.add(lmap);
                }
            }
        }

        map.put("resourcenum",totalnum);
        map.put("levels",levelsmap);

        return map;
    }
    
    private boolean isExistLeves(Integer level, List<Map> list) {
        for (Map m : list) {
            Object levelid = m.get("level");
            if (levelid!=null && levelid.toString().equals(level.toString())) {
                return true;
            }
        }
        return false;
    }

    private boolean isExistTypes(Integer resourcetype, List<ResourceTypeVo> list) {
        for (ResourceTypeVo rt : list) {
            if (rt.getRtype().equals(resourcetype)) {
                return true;
            }
        }
        return false;
    }


    //获取试题科目统计
    public Map listQuestionSubjectNum() {
        Map map = new HashMap();
        List<RSubjectVo> lst = regionAnalyzeMapper.listQuestionSubjectNum();

        List<RSubjectVo> subjects = new ArrayList<>();
        List<Map> levels = new ArrayList<>();
        Integer totalnum = 0;
        if(lst!=null && lst.size()>0){
            totalnum = lst.stream().mapToInt(RSubjectVo::getSnum).sum();
            for(RSubjectVo s : lst){
                if(!isExistLeves(s.getLevel(),levels)){
                    //学段下科目
                    List<RSubjectVo> levelst = lst.stream().filter(rSubjectVo -> rSubjectVo.getLevel().equals(s.getLevel())).collect(Collectors.toList());
                    Integer levelnum = levelst.stream().mapToInt(RSubjectVo::getSnum).sum();
                    double levelrate = N_Utils.getIntegerDivideAndMulitiply(levelnum,totalnum);

                    RSubjectVo maxsubject = levelst.stream().max(Comparator.comparing(RSubjectVo::getSnum)).get();
                    double maxsubrate = N_Utils.getIntegerDivideAndMulitiply(maxsubject.getSnum(), levelnum);

                    Integer ptnum = levelst.stream().mapToInt(RSubjectVo::getPtnum).sum();
                    Integer xbnum = levelst.stream().mapToInt(RSubjectVo::getXbnum).sum();
                    double ptrate = N_Utils.getIntegerDivideAndMulitiply(ptnum, levelnum);
                    double xbrate = N_Utils.getIntegerDivideAndMulitiply(xbnum, levelnum);

                    List<Map> lslist = new ArrayList<>();
                    for(RSubjectVo rs : levelst){
                        Map smap = new HashMap();
                        double srate = N_Utils.getIntegerDivideAndMulitiply(rs.getSnum(),levelnum);
                        smap.put("subjectname",rs.getSubjectname());
                        smap.put("snum",rs.getSnum());
                        smap.put("srate",srate);
                        lslist.add(smap);
                    }

                    Map levelm = new HashMap();
                    levelm.put("level",s.getLevel());
                    levelm.put("levelnum",levelnum);
                    levelm.put("levelrate",levelrate);
                    levelm.put("maxsubject",maxsubject.getSubjectname());
                    levelm.put("maxnum",maxsubject.getSnum());
                    levelm.put("maxrate",maxsubrate);
                    levelm.put("subjects",lslist);
                    levelm.put("ptrate",ptrate);
                    levelm.put("xbrate",xbrate);

                    levels.add(levelm);
                }
            }
        }

        map.put("questionnum",totalnum);
        map.put("levels",levels);

        return map;
    }

    //获取学校列表
    public List<Map> listSchool(RegionParam param) {
        return regionAnalyzeMapper.listSchool(param);
    }

    //获取学段班级、教师、学生总量
    public List<Map> listClassTeacherStudentNum(RegionParam param) {
        return regionAnalyzeMapper.listClassTeacherStudentNum(param);
    }

    //近一个月教学统计
    public Map listPaperCommitMonth(RegionParam param) {
        List<WorkVo> works = regionAnalyzeMapper.listPaperCommitMonth(param);
        Map map = new HashMap();

        if (works != null && works.size() > 0) {
            for (WorkVo w : works) {
                List<WorkDetailVo> detials = w.getDetails();
                Integer stunum = detials.stream().mapToInt(WorkDetailVo::getStunum).sum();
                Integer commitnum = detials.stream().mapToInt(WorkDetailVo::getCommitnum).sum();

                double commitrate = N_Utils.getIntegerDivideAndMulitiply(commitnum, stunum);
                w.setNumrate(commitrate);
            }

            //最高提交率
            WorkVo maxobj = works.stream().max(Comparator.comparing(WorkVo::getNumrate)).get();
            //平均提交率
            double avgnumdouble = works.stream().mapToDouble(WorkVo::getNumrate).average().getAsDouble();

            map.put("avgrate", N_Utils.formatDouble(avgnumdouble,2));
            map.put("maxrate", maxobj.getNumrate());
            map.put("maxschool", maxobj.getSchoolname());
            map.put("shortname", maxobj.getShortname());
        }
        return map;
    }

    //近一个月教学统计--各教学任务
    public List<WorkRtnVo> listWorkCommitMonth(RegionParam param) {

        List<WorkRtnVo> rtnmap = new ArrayList<>();
        boolean noexist = false;

        //作业
        List<WorkVo> papers = regionAnalyzeMapper.listPaperCommitMonth(param);
        if (N_Utils.isListNotEmpty(papers)) {
            for (WorkVo w : papers) {
                List<WorkDetailVo> detials = w.getDetails();
                Integer stunum = detials.stream().mapToInt(WorkDetailVo::getStunum).sum();
                Integer commitnum = detials.stream().mapToInt(WorkDetailVo::getCommitnum).sum();
                Integer checknum = detials.stream().mapToInt(WorkDetailVo::getChecknum).sum();
                double commitrate = N_Utils.getIntegerDivideAndMulitiply(commitnum, stunum);

                double checkrate = 0;
                if (commitnum != null && commitnum > 0) {
                    checkrate = N_Utils.getIntegerDivideAndMulitiply(checknum, commitnum);
                }

                WorkRtnVo workRtnVo = new WorkRtnVo();
                workRtnVo.setSchoolid(w.getSchoolid());
                workRtnVo.setSchoolname(w.getSchoolname());
                workRtnVo.setShortname(w.getShortname());
                workRtnVo.setPapercommit(commitrate);
                workRtnVo.setPapercheck(checkrate);

                rtnmap.add(workRtnVo);
            }
        }
        //课堂考勤
        List<Map> rooms = regionAnalyzeMapper.listRoomCommitMonth(param);
        if (N_Utils.isListNotEmpty(rooms)) {
            for (Map map : rooms) {
                Integer stunum = Integer.parseInt(map.get("stunum").toString());
                Integer commitnum = Integer.parseInt(map.get("commitnum").toString());

                double commitrate = N_Utils.getIntegerDivideAndMulitiply(commitnum, stunum);

                Integer schoolid = Integer.parseInt(map.get("schoolid").toString());
                WorkRtnVo workRtnVo = rtnListWorkRtnVo(rtnmap, (schoolid));
                if (workRtnVo == null) {
                    workRtnVo = new WorkRtnVo();
                    workRtnVo.setSchoolid(schoolid);
                    workRtnVo.setSchoolname(map.get("schoolname").toString());
                    noexist = true;
                }
                workRtnVo.setRoomrate(commitrate);
                if (noexist) {
                    rtnmap.add(workRtnVo);
                    noexist = false;
                }
            }
        }
        //预习
        List<WorkVo> guides = regionAnalyzeMapper.listGuideCommitMonth(param);
        if (N_Utils.isListNotEmpty(guides)) {
            for (WorkVo w : guides) {
                List<WorkDetailVo> detials = w.getDetails();
                Integer stunum = detials.stream().mapToInt(WorkDetailVo::getStunum).sum();
                Integer commitnum = detials.stream().mapToInt(WorkDetailVo::getCommitnum).sum();
                double commitrate = N_Utils.getIntegerDivideAndMulitiply(commitnum, stunum);

                WorkRtnVo workRtnVo = rtnListWorkRtnVo(rtnmap, w.getSchoolid());
                if (workRtnVo == null) {
                    workRtnVo = new WorkRtnVo();
                    workRtnVo.setSchoolid(w.getSchoolid());
                    workRtnVo.setSchoolname(w.getSchoolname());
                    workRtnVo.setShortname(w.getShortname());
                    noexist = true;
                }
                workRtnVo.setGuiderate(commitrate);
                if (noexist) {
                    rtnmap.add(workRtnVo);
                    noexist = false;
                }
            }
        }
        //背诵
        List<WorkVo> recites = regionAnalyzeMapper.listReciteCommitMonth(param);
        if (N_Utils.isListNotEmpty(recites)) {
            for (WorkVo w : recites) {
                List<WorkDetailVo> detials = w.getDetails();
                Integer stunum = detials.stream().mapToInt(WorkDetailVo::getStunum).sum();
                Integer commitnum = detials.stream().mapToInt(WorkDetailVo::getCommitnum).sum();
                double commitrate = N_Utils.getIntegerDivideAndMulitiply(commitnum, stunum);

                WorkRtnVo workRtnVo = rtnListWorkRtnVo(rtnmap, w.getSchoolid());
                if (workRtnVo == null) {
                    workRtnVo = new WorkRtnVo();
                    workRtnVo.setSchoolid(w.getSchoolid());
                    workRtnVo.setSchoolname(w.getSchoolname());
                    workRtnVo.setShortname(w.getShortname());
                    noexist = true;
                }
                workRtnVo.setReciterate(commitrate);
                if (noexist) {
                    rtnmap.add(workRtnVo);
                    noexist = false;
                }
            }
        }

        return rtnmap;
    }

    //用户是否存在集合中
    private WorkRtnVo rtnListWorkRtnVo(List<WorkRtnVo> lst, Integer schoolid) {
        for (WorkRtnVo w : lst) {
            if (w.getSchoolid().equals(schoolid)) {
                return w;
            }
        }
        return null;
    }

    //近一个月布置作业次数
    public Map listPapernumMonth(RegionParam param) {
        List<WorkVo> papers = regionAnalyzeMapper.listPapernumMonth(param);

        Map map = new HashMap();
        if (papers != null && papers.size() > 0) {
            //最大数量对象
            WorkVo maxnum = papers.stream().max(Comparator.comparing(WorkVo::getNum)).get();
            //平均
            double avgnumdouble = papers.stream().mapToInt(WorkVo::getNum).average().getAsDouble();
            Integer avgnum = new Double(avgnumdouble).intValue();

            map.put("avgnum", avgnum);
            map.put("maxnum", maxnum.getNum());
            map.put("maxschool", maxnum.getSchoolname());
            map.put("shortname", maxnum.getShortname());

            map.put("details", papers);
        }
        return map;

    }

    //近一个月课堂使用情况统计——使用次数
    public Map listRoomNumMonth(RegionParam param) {
        Map map = new HashMap();

        List<WorkVo> rooms = regionAnalyzeMapper.listRoomNumMonth(param);
        if (rooms != null && rooms.size() > 0) {
            //最大数量对象
            WorkVo maxnum = rooms.stream().max(Comparator.comparing(WorkVo::getNum)).get();
            //平均
            double avgnumdouble = rooms.stream().mapToInt(WorkVo::getNum).average().getAsDouble();
            Integer avgnum = new Double(avgnumdouble).intValue();

            map.put("avgnum", avgnum);
            map.put("maxnum", maxnum.getNum());
            map.put("maxschool", maxnum.getSchoolname());
            map.put("shortname", maxnum.getShortname());
        }
        return map;
    }

    //近一个月课堂使用情况统计——课堂互动
    public List<Map> listRoomAskNumMonth2(RegionParam param) {
        return regionAnalyzeMapper.listRoomAskNumMonth2(param);
    }
}
