package com.ruoyi.web.service;

import com.ruoyi.syzy.domain.BBusiWishScoreGroups;
import org.apache.commons.collections4.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

public class ScoreGroupCalculator {
    private Map<String, List<BBusiWishScoreGroups>> yearScoreGroupsMap;
    private Set<String> courseSet;

    public ScoreGroupCalculator(List<BBusiWishScoreGroups> groupList) {
        Collections.sort(groupList, new Comparator<BBusiWishScoreGroups>() {
            @Override
            public int compare(BBusiWishScoreGroups o1, BBusiWishScoreGroups o2) {
                return o1.getScore().compareTo(o2.getScore());
            }
        });
        courseSet = groupList.stream().map(t -> t.getMode()).collect(Collectors.toSet());
        yearScoreGroupsMap = groupList.stream().collect(Collectors.groupingBy(t -> buildKey(t.getYear(), t.getMode())));
        if(CollectionUtils.isEmpty(groupList)) {
            return;
        }
    }

    public Integer getRankIgnoreLow(Integer year, String mode, Integer score) {
        return (null == score || score < 200) ? null : getRank2(year, mode, score);
    }

    public Integer getRank(Integer year, String mode, Integer score) {
        return (null == score) ? null : getRank2(year, mode, score);
    }

    public Integer getRank2(Integer year, String mode, Integer score) {
        BBusiWishScoreGroups scoreGroups = getScoreGroupByScore(year, mode, score);
        return null != scoreGroups ? scoreGroups.getLowestRank() : null;
    }

    public Integer getScore(Integer year, String mode, Integer rank) {
        List<BBusiWishScoreGroups> l = yearScoreGroupsMap.get(buildKey(year, mode));
        if (null == l) {
            return null;
        }
        Optional<BBusiWishScoreGroups> optionalBBusiWishScoreGroups = l.stream().filter(v -> rank <= v.getLowestRank() && rank >= v.getHighestRank()).findFirst();
        /*int left = 0;
        int right = l.size() - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            BBusiWishScoreGroups v = l.get(mid);
            if (rank <= v.getLowestRank() && rank >= v.getHighestRank()) {
                return v.getScore(); // 找到目标，返回索引
            } else if (v.getLowestRank() > rank) {
                left = mid + 1; // 在右半区继续查找
            } else {
                right = mid - 1; // 在左半区继续查找
            }
        }*/
        return optionalBBusiWishScoreGroups.isPresent() ? optionalBBusiWishScoreGroups.get().getScore() : null;
    }

    public BBusiWishScoreGroups getScoreGroupByScore(Integer year, String mode, Integer score) {
        List<BBusiWishScoreGroups> l = yearScoreGroupsMap.get(buildKey(year, mode));
        if (CollectionUtils.isEmpty(l) || null == score || score > l.get(l.size() - 1).getMaxScore()) {
            return null;
        }
        Optional<BBusiWishScoreGroups> optionalBBusiWishScoreGroups = l.stream().filter(v -> score >= v.getScore() && score <= v.getMaxScore()).findFirst();
        /*
        int left = 0;
        int right = l.size() - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;

            BBusiWishScoreGroups v = l.get(mid);
            if (score >= v.getScore() && score <= v.getMaxScore()) {
                return v; // 找到目标，返回索引
            } else if (v.getScore() < score) {
                left = mid + 1; // 在右半区继续查找
            } else {
                right = mid - 1; // 在左半区继续查找
            }
        }*/
        return optionalBBusiWishScoreGroups.isPresent() ? optionalBBusiWishScoreGroups.get() : null;
    }

    public BBusiWishScoreGroups getBatchRange(Map<String, List<BBusiWishScoreGroups>> yearBatchRangeMap, Integer year, Integer matchBatch) {
        return getBatchRange(yearBatchRangeMap, year, null, matchBatch);
    }

    public BBusiWishScoreGroups getBatchRange(Map<String, List<BBusiWishScoreGroups>> yearBatchRangeMap, Integer year, Integer liberalScience, Integer matchBatch) {
        List<BBusiWishScoreGroups> rangeList = yearBatchRangeMap.get(null != liberalScience ? year + "_" + liberalScience : year.toString());
        if (null != rangeList) {
            for (BBusiWishScoreGroups range : rangeList) {
                if (range.getType().equals(matchBatch)) {
                    return range;
                }
            }
        }
        return null;
    }

    public Integer getMaxScore(Integer year, String mode) {
        List<BBusiWishScoreGroups> l = yearScoreGroupsMap.get(buildKey(year, mode));
        return CollectionUtils.isNotEmpty(l) ? l.get(l.size() - 1).getMaxScore() : null;
    }

    public Boolean isMixCourse() {
        return courseSet.size() > 2;
    }

    public static Integer getLiberalScience(String type) {
        if("物理".equals(type) || "理科".equals(type)) {
            return 1;
        } else if("历史".equals(type) || "文科".equals(type)) {
            return 0;
        }
        return 2;
    }

    private String buildKey(Integer year, String mode) {
        return year + "_" + mode;
    }
}
