package com.tzld.piaoquan.recommend.server.service.score4recall.strategy;

import com.tzld.piaoquan.recommend.server.service.score.ScorerConfigInfo;
import com.tzld.piaoquan.recommend.server.service.score4recall.AbstractScorer4Recall;
import com.tzld.piaoquan.recommend.server.service.score4recall.model4recall.Model4RecallLongTerm;
import org.apache.commons.lang3.tuple.Pair;
import java.util.*;

public class RegionRecallScorerV7LongTerm extends AbstractScorer4Recall {

    public RegionRecallScorerV7LongTerm(ScorerConfigInfo configInfo) {
        super(configInfo);
    }
    @Override
    public void loadModel() {
        doLoadModel(Model4RecallLongTerm.class);
    }

    @Override
    public List<Pair<Long, Double>> recall(Map<String, String> params){
        Model4RecallLongTerm model = (Model4RecallLongTerm) this.getModel();
        Map<String, List<Pair<Long, Double>>> kv = model.kv;
        Set<Pair<Long, Double>> uniqueResults = new LinkedHashSet<>();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            String key = entry.getKey();
            int count = Integer.parseInt(entry.getValue());
            if (kv.containsKey(key)) {
                List<Pair<Long, Double>> copy = new ArrayList<>(kv.get(key));
                // 先随机，再截断。
                List<Pair<Long, Double>> selected = getWeightedRandomElements(copy, count);
                uniqueResults.addAll(selected);
            }
        }
        return new ArrayList<>(uniqueResults); // 转换回 List 并返回
    }

    public static List<Pair<Long, Double>> getWeightedRandomElements(List<Pair<Long, Double>> list, int count) {
        if (list == null || list.isEmpty()) {
            return new ArrayList<>(0);
        }
        if (count >= list.size()) {
            return new ArrayList<>(list);
        }

        // 计算权重总和
        double totalWeight = list.stream().mapToDouble(Pair::getRight).sum();

        // 使用加权随机选择
        List<Pair<Long, Double>> result = new ArrayList<>();
        Random random = new Random();

        for (int i = 0; i < count; i++) {
            double rand = random.nextDouble() * totalWeight; // 生成一个0到totalWeight之间的随机数
            double cumulativeWeight = 0.0;

            for (Pair<Long, Double> pair : list) {
                cumulativeWeight += pair.getRight(); // 累加权重
                if (rand <= cumulativeWeight) {
                    result.add(pair); // 选择当前元素
                    totalWeight -= pair.getRight(); // 更新总权重
                    list.remove(pair); // 防止重复选择
                    break;
                }
            }
        }

        return result;
    }

}