package com.qmth.teachcloud.report;

import com.alibaba.fastjson.JSONObject;
import com.qmth.teachcloud.report.business.mapper.CourseReportMapper;
import org.junit.Test;
import org.junit.platform.commons.util.CollectionUtils;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

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

@SpringBootTest(classes = {TeachcloudReportApplication.class})
@RunWith(SpringRunner.class)
public class XfTest {


    @Resource
    private CourseReportMapper courseReportMapper;

    /**
     * 中等难度
     */
    @Test
    public void trail() {
        List<Map<String, Object>> studentPaperList = courseReportMapper.list1();

        Map<String, List<Map<String, Object>>> scoreRateListMap = studentPaperList.stream().collect(Collectors.groupingBy(m -> m.get("num").toString()));
        List<Map<String, Object>> finalList = new ArrayList<>();
        for (Map.Entry<String, List<Map<String, Object>>> entry : scoreRateListMap.entrySet()) {
            Map<String, Object> scoreRateMap = new HashMap<>();
            scoreRateMap.put("num", entry.getKey());
            double avgScoreRate = entry.getValue().stream().map(m -> {
                double rate = new BigDecimal(m.get("score").toString()).divide(new BigDecimal(m.get("full_score").toString()), 8, BigDecimal.ROUND_HALF_UP).doubleValue();
                return rate;
            }).collect(Collectors.averagingDouble(m -> m));
            scoreRateMap.put("scoreRate", new BigDecimal(avgScoreRate).setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue());
            scoreRateMap.put("scoreRate8", avgScoreRate);
            finalList.add(scoreRateMap);
        }

        List<String> nums = finalList.stream().filter(m -> Double.parseDouble(m.get("scoreRate").toString()) >= 0.3 && Double.parseDouble(m.get("scoreRate").toString()) <= 0.7).map(m -> m.get("num").toString()).collect(Collectors.toList());
        System.out.println("中等难度题：" + JSONObject.toJSONString(nums));

        List<Map<String, Object>> mapList = studentPaperList.stream().filter(m -> nums.contains(m.get("num").toString())).collect(Collectors.toList());
        double middleScoreRate = mapList.stream().map(m -> {
            double rate = new BigDecimal(m.get("score").toString()).divide(new BigDecimal(m.get("full_score").toString()), 8, BigDecimal.ROUND_HALF_UP).doubleValue();
            return rate;
        }).collect(Collectors.averagingDouble(m -> m));

        System.out.println("全校中等难度得分率：" + middleScoreRate);


        List<Map<String, Object>> mapList2 = studentPaperList.stream().filter(m -> nums.contains(m.get("num").toString()) && Objects.equals(m.get("inspect_college_id").toString(), "135697788569649152")).collect(Collectors.toList());
        double middleScoreRate2 = mapList2.stream().map(m -> {
            double rate = new BigDecimal(m.get("score").toString()).divide(new BigDecimal(m.get("full_score").toString()), 8, BigDecimal.ROUND_HALF_UP).doubleValue();
            return rate;
        }).collect(Collectors.averagingDouble(m -> m));

        System.out.println("本院中等难度得分率：" + middleScoreRate2);
    }


    /**
     * 效度
     */
    @Test
    public void trail1() {
        List<Map<String, Object>> studentPaperList = courseReportMapper.list1();

        // 所有题卡
        List<String> nums = studentPaperList.stream().map(m -> m.get("num").toString()).collect(Collectors.toList());

        Map<String, List<Map<String, Object>>> studentMap = studentPaperList.stream().collect(Collectors.groupingBy(m -> m.get("id").toString()));
        List<Map<String, Object>> studentScoreList = new ArrayList<>();
        // 计算单个考生总分
        for (Map.Entry<String, List<Map<String, Object>>> entry : studentMap.entrySet()) {
            Map<String, Object> scoreRateMap = new HashMap<>();
            scoreRateMap.put("id", entry.getKey());
            double totalScore = entry.getValue().stream().map(m -> new BigDecimal(m.get("score").toString()).setScale(8, BigDecimal.ROUND_HALF_UP).doubleValue()).collect(Collectors.summingDouble(m -> m));
            scoreRateMap.put("totalScore", totalScore);
            studentScoreList.add(scoreRateMap);
        }

        // 计算百分等级
        List<Map<String, Object>> newList = studentScoreList.stream().map(m -> {
            double score = Double.parseDouble(m.get("totalScore").toString());
            long lowCount = studentScoreList.stream().filter(m1 -> Double.parseDouble(m1.get("totalScore").toString()) < score).count();
            long equelCount = studentScoreList.stream().filter(m1 -> Double.parseDouble(m1.get("totalScore").toString()) == score).count();
            BigDecimal one = new BigDecimal(lowCount).add(new BigDecimal(equelCount).divide(new BigDecimal("2")));
            int grade = one.multiply(new BigDecimal("100")).divide(new BigDecimal(studentScoreList.size()), 0, BigDecimal.ROUND_DOWN).intValue();
            m.put("grade", grade);
            return m;
        }).collect(Collectors.toList());

        int count27 = new BigDecimal(newList.size()).multiply(new BigDecimal("27")).divide(new BigDecimal("100"), 0, BigDecimal.ROUND_DOWN).intValue();
        // 前27%考生
        newList.sort((o1, o2) -> Integer.parseInt(o2.get("grade").toString()) - Integer.parseInt(o1.get("grade").toString()));
        List<String> before27Ids = newList.stream().limit(count27).map(m -> m.get("id").toString()).collect(Collectors.toList());

        List<Map<String, Object>> before27 = studentPaperList.stream().filter(m -> before27Ids.contains(m.get("id").toString())).collect(Collectors.toList());
        Map<String, List<Map<String, Object>>> scoreRateListMap = before27.stream().collect(Collectors.groupingBy(m -> m.get("num").toString()));
        Map<String, Object> amap = new HashMap<>();
        for (Map.Entry<String, List<Map<String, Object>>> entry : scoreRateListMap.entrySet()) {
            double avgScoreRate = entry.getValue().stream().map(m -> {
                double rate = new BigDecimal(m.get("score").toString()).divide(new BigDecimal(m.get("full_score").toString()), 8, BigDecimal.ROUND_HALF_UP).doubleValue();
                return rate;
            }).collect(Collectors.averagingDouble(m -> m));
            amap.put(entry.getKey(), new BigDecimal(avgScoreRate).setScale(8, BigDecimal.ROUND_HALF_UP).doubleValue());
        }

        // 后27%考生
        newList.sort(Comparator.comparingInt(o -> Integer.parseInt(o.get("grade").toString())));

        List<String> after27Ids = newList.stream().limit(count27).map(m -> m.get("id").toString()).collect(Collectors.toList());
        List<Map<String, Object>> after27 = studentPaperList.stream().filter(m -> after27Ids.contains(m.get("id").toString())).collect(Collectors.toList());

        Map<String, List<Map<String, Object>>> scoreRateListMap2 = after27.stream().collect(Collectors.groupingBy(m -> m.get("num").toString()));
        Map<String, Object> bmap = new HashMap<>();
        for (Map.Entry<String, List<Map<String, Object>>> entry : scoreRateListMap2.entrySet()) {
            double avgScoreRate = entry.getValue().stream().map(m -> {
                double rate = new BigDecimal(m.get("score").toString()).divide(new BigDecimal(m.get("full_score").toString()), 8, BigDecimal.ROUND_HALF_UP).doubleValue();
                return rate;
            }).collect(Collectors.averagingDouble(m -> m));
            bmap.put(entry.getKey(), new BigDecimal(avgScoreRate).setScale(8, BigDecimal.ROUND_HALF_UP).doubleValue());
        }

        // 效度
        Map<String, Object> finalMap = new HashMap<>();
        for (String num : nums) {
            double a27 = Double.parseDouble(amap.get(num).toString());
            double b27 = Double.parseDouble(bmap.get(num).toString());
            finalMap.put(num, a27 - b27);
        }

        System.out.println("效度：" + JSONObject.toJSONString(finalMap));
    }

    /**
     * 效度
     */
    @Test
    public void trail2() {
        List<Map<String, Object>> studentPaperList = courseReportMapper.list1();

        // 所有题卡
        List<String> nums = studentPaperList.stream().map(m -> m.get("num").toString()).collect(Collectors.toList());

        Map<String, List<Map<String, Object>>> studentMap = studentPaperList.stream().collect(Collectors.groupingBy(m -> m.get("id").toString()));
        List<Map<String, Object>> studentScoreList = new ArrayList<>();
        // 计算单个考生总分
        for (Map.Entry<String, List<Map<String, Object>>> entry : studentMap.entrySet()) {
            Map<String, Object> scoreRateMap = new HashMap<>();
            scoreRateMap.put("id", entry.getKey());
            double totalScore = entry.getValue().stream().map(m -> new BigDecimal(m.get("score").toString()).setScale(8, BigDecimal.ROUND_HALF_UP).doubleValue()).collect(Collectors.summingDouble(m -> m));
            scoreRateMap.put("totalScore", totalScore);
            studentScoreList.add(scoreRateMap);
        }

        // 计算百分等级
        List<Map<String, Object>> newList = studentScoreList.stream().map(m -> {
            double score = Double.parseDouble(m.get("totalScore").toString());
            long lowCount = studentScoreList.stream().filter(m1 -> Double.parseDouble(m1.get("totalScore").toString()) < score).count();
            long equelCount = studentScoreList.stream().filter(m1 -> Double.parseDouble(m1.get("totalScore").toString()) == score).count();
            BigDecimal one = new BigDecimal(lowCount).add(new BigDecimal(equelCount).divide(new BigDecimal("2")));
            int grade = one.multiply(new BigDecimal("100")).divide(new BigDecimal(studentScoreList.size()), 0, BigDecimal.ROUND_DOWN).intValue();
            m.put("grade", grade);
            return m;
        }).collect(Collectors.toList());

        int count27 = new BigDecimal(newList.size()).multiply(new BigDecimal("27")).divide(new BigDecimal("100"), 0, BigDecimal.ROUND_DOWN).intValue();
        // 前27%考生
        newList.sort((o1, o2) -> Integer.parseInt(o2.get("grade").toString()) - Integer.parseInt(o1.get("grade").toString()));
        int beforeGrade = Integer.parseInt(newList.get(count27).get("grade").toString());
        List<String> before27Ids = newList.stream().filter(m -> Integer.parseInt(m.get("grade").toString()) >= beforeGrade).map(m->m.get("id").toString()).collect(Collectors.toList());

        List<Map<String, Object>> before27 = studentPaperList.stream().filter(m -> before27Ids.contains(m.get("id").toString())).collect(Collectors.toList());
        Map<String, List<Map<String, Object>>> scoreRateListMap = before27.stream().collect(Collectors.groupingBy(m -> m.get("num").toString()));
        Map<String, Object> amap = new HashMap<>();
        for (Map.Entry<String, List<Map<String, Object>>> entry : scoreRateListMap.entrySet()) {
            double avgScoreRate = entry.getValue().stream().map(m -> {
                double rate = new BigDecimal(m.get("score").toString()).divide(new BigDecimal(m.get("full_score").toString()), 8, BigDecimal.ROUND_HALF_UP).doubleValue();
                return rate;
            }).collect(Collectors.averagingDouble(m -> m));
            amap.put(entry.getKey(), new BigDecimal(avgScoreRate).setScale(8, BigDecimal.ROUND_HALF_UP).doubleValue());
        }

        // 后27%考生
        newList.sort(Comparator.comparingInt(o -> Integer.parseInt(o.get("grade").toString())));
        int afterGrade = Integer.parseInt(newList.get(count27).get("grade").toString());
        List<String> after27Ids = newList.stream().filter(m -> Integer.parseInt(m.get("grade").toString()) <= afterGrade).map(m->m.get("id").toString()).collect(Collectors.toList());
//        List<String> after27Ids = newList.stream().limit(count27).map(m -> m.get("id").toString()).collect(Collectors.toList());
        List<Map<String, Object>> after27 = studentPaperList.stream().filter(m -> after27Ids.contains(m.get("id").toString())).collect(Collectors.toList());

        Map<String, List<Map<String, Object>>> scoreRateListMap2 = after27.stream().collect(Collectors.groupingBy(m -> m.get("num").toString()));
        Map<String, Object> bmap = new HashMap<>();
        for (Map.Entry<String, List<Map<String, Object>>> entry : scoreRateListMap2.entrySet()) {
            double avgScoreRate = entry.getValue().stream().map(m -> {
                double rate = new BigDecimal(m.get("score").toString()).divide(new BigDecimal(m.get("full_score").toString()), 8, BigDecimal.ROUND_HALF_UP).doubleValue();
                return rate;
            }).collect(Collectors.averagingDouble(m -> m));
            bmap.put(entry.getKey(), new BigDecimal(avgScoreRate).setScale(8, BigDecimal.ROUND_HALF_UP).doubleValue());
        }

        // 效度
        Map<String, Object> finalMap = new HashMap<>();
        for (String num : nums) {
            double a27 = Double.parseDouble(amap.get(num).toString());
            double b27 = Double.parseDouble(bmap.get(num).toString());
            finalMap.put(num, a27 - b27);
        }

        System.out.println("效度：" + JSONObject.toJSONString(finalMap));
    }

}
