package com.tzld.piaoquan.recommend.server.service.score;

import com.tzld.piaoquan.recommend.server.common.base.RankItem;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class VovH24Weight562Scorer {
    public static void scoring(Map<String, Double> mergeWeight, Map<String, Map<String, String>> vid2VovFeatureMap, final List<RankItem> items) {
        try {
            if (MapUtils.isEmpty(mergeWeight) || MapUtils.isEmpty(vid2VovFeatureMap) || CollectionUtils.isEmpty(items)) {
                return;
            }

            // 融合权重
            double vov_thresh = mergeWeight.getOrDefault("vov_thresh", 0.1);
            double view_thresh = mergeWeight.getOrDefault("view_thresh", 1535.0);
            double level50_vov = mergeWeight.getOrDefault("level50_vov", 0.123);
            double level_95_vov = mergeWeight.getOrDefault("level_95_vov", 0.178);
            double beta_vov = mergeWeight.getOrDefault("beta_vov", 100.0);

            List<Double> weightList = new ArrayList<>(7);
            weightList.add(mergeWeight.getOrDefault("d2_ago_vov_w", 0.0));
            weightList.add(mergeWeight.getOrDefault("d1_ago_vov_w", 0.0));
            weightList.add(mergeWeight.getOrDefault("h48_ago_vov_w", 0.0));
            weightList.add(mergeWeight.getOrDefault("h24_ago_vov_w", 0.0));
            weightList.add(mergeWeight.getOrDefault("h3_ago_vov_w", 0.0));
            weightList.add(mergeWeight.getOrDefault("h2_ago_vov_w", 0.0));
            weightList.add(mergeWeight.getOrDefault("h1_ago_vov_w", 0.0));

            for (RankItem item : items) {
                // 获取VoV输入特征
                double h1_ago_vov = Double.parseDouble(vid2VovFeatureMap.getOrDefault(item.getVideoId() + "", new HashMap<>())
                        .getOrDefault("h1_ago_vov", "-2")); // 如果没有时，默认为多少？？ 需要考虑
                double h2_ago_vov = Double.parseDouble(vid2VovFeatureMap.getOrDefault(item.getVideoId() + "", new HashMap<>())
                        .getOrDefault("h2_ago_vov", "-2")); // 如果没有时，默认为多少？？ 需要考虑
                double h3_ago_vov = Double.parseDouble(vid2VovFeatureMap.getOrDefault(item.getVideoId() + "", new HashMap<>())
                        .getOrDefault("h3_ago_vov", "-2")); // 如果没有时，默认为多少？？ 需要考虑
                double h24_ago_vov = Double.parseDouble(vid2VovFeatureMap.getOrDefault(item.getVideoId() + "", new HashMap<>())
                        .getOrDefault("h24_ago_vov", "-2")); // 如果没有时，默认为多少？？ 需要考虑
                double h48_ago_vov = Double.parseDouble(vid2VovFeatureMap.getOrDefault(item.getVideoId() + "", new HashMap<>())
                        .getOrDefault("h48_ago_vov", "-2")); // 如果没有时，默认为多少？？ 需要考虑
                double d1_ago_vov = Double.parseDouble(vid2VovFeatureMap.getOrDefault(item.getVideoId() + "", new HashMap<>())
                        .getOrDefault("d1_ago_vov", "-2")); // 如果没有时，默认为多少？？ 需要考虑
                double d2_ago_vov = Double.parseDouble(vid2VovFeatureMap.getOrDefault(item.getVideoId() + "", new HashMap<>())
                        .getOrDefault("d2_ago_vov", "-2")); // 如果没有时，默认为多少？？ 需要考虑
                double h1_ago_view = Double.parseDouble(vid2VovFeatureMap.getOrDefault(item.getVideoId() + "", new HashMap<>())
                        .getOrDefault("h1_ago_view", "-2")); // 如果没有时，默认为多少？？ 需要考虑

                // log feature
                item.getScoresMap().put("h1_ago_vov", h1_ago_vov);
                item.getScoresMap().put("h2_ago_vov", h2_ago_vov);
                item.getScoresMap().put("h3_ago_vov", h3_ago_vov);
                item.getScoresMap().put("h24_ago_vov", h24_ago_vov);
                item.getScoresMap().put("h48_ago_vov", h48_ago_vov);
                item.getScoresMap().put("d1_ago_vov", d1_ago_vov);
                item.getScoresMap().put("d2_ago_vov", d2_ago_vov);
                item.getScoresMap().put("h1_ago_view", h1_ago_view);

                List<Double> featureList = new ArrayList<>(7);
                featureList.add(d2_ago_vov);
                featureList.add(d1_ago_vov);
                featureList.add(h48_ago_vov);
                featureList.add(h24_ago_vov);
                featureList.add(h3_ago_vov);
                featureList.add(h2_ago_vov);
                featureList.add(h1_ago_vov);
                double vovScore562 = calcScore(featureList, weightList, item, vov_thresh, view_thresh, h1_ago_view, level50_vov, level_95_vov, beta_vov);
                item.getScoresMap().put("vovScore562", vovScore562);
            }
        } catch (Exception e) {
            log.error(String.format("something is wrong in VovH24Weight562Scorer with {}", e));
        }
    }


    private static double calcScore(List<Double> featureList, List<Double> weightList, RankItem rankItem,
                                    double vov_thresh, double view_thresh, double h1_ago_view, double level50_vov, double level_95_vov, double beta_vov) {
        // 检查 h1_ago_view 条件
        if (h1_ago_view == -2 || h1_ago_view == -1 || h1_ago_view < view_thresh) {
            return 0;
        }

        // 计算有效特征的总权重和得分
        double score = 0;
        List<Integer> validIndices = new ArrayList<>();
        for (int i = 0; i < featureList.size(); i++) {
            if (featureList.get(i) != -1) {
                validIndices.add(i);
            }
        }

        // 如果没有有效特征，返回 0
        if (validIndices.isEmpty()) {
            return 0;
        }

        // 计算得分，动态调整权重
        for (int index : validIndices) {
            double weight = weightList.get(index);
            score += featureList.get(index) * weight;
        }

        // 调整vov
        if (score < vov_thresh) {
            score = 0;
        } else {
            double term1 = 1 / (1 + Math.exp(-1 * beta_vov * (score - level50_vov)));
            double term2 = 1 + Math.exp(-1 * beta_vov * (level_95_vov - level50_vov));
            score = term1 * term2;
        }
        return score;
    }
}
