// package com.tzld.piaoquan.ad.engine.service.predict.v2;
//
// import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
// import com.tzld.piaoquan.ad.engine.commons.util.NumUtil;
// import com.tzld.piaoquan.ad.engine.service.feature.Feature;
// import com.tzld.piaoquan.ad.engine.service.feature.FeatureService;
// import lombok.extern.slf4j.Slf4j;
// import org.apache.commons.collections4.MapUtils;
// import org.springframework.beans.factory.annotation.Autowired;
// import org.springframework.stereotype.Service;
//
// import java.util.HashMap;
// import java.util.Map;
//
// @Slf4j
// @Service
// public class PredictServiceV2 extends BasicPredict {
//
//     @Autowired
//     private FeatureService featureService;
//
//     @ApolloJsonValue("${exp.713.config:{}}")
//     private Map<String, Double> exp713Config;
//
//     @Override
//     public Map<String, Object> predict(PredictContext ctx) {
//         Feature feature = featureService.getPredictFeature(ctx);
//         Map<String, Map<String, String>> userFeature = feature.getUserFeature();
//         Map<String, String> featureMap = userFeature.getOrDefault("alg_ad_crowd_choose_feature_v2", new HashMap<>());
//         double minScore = exp713Config.getOrDefault("minScore", 0.1d);
//         double maxScore = exp713Config.getOrDefault("maxScore", 0.8d);
//         double score = maxScore;
//
//         ctx.getLogParam().setBIsNewUser(true);
//
//         if (MapUtils.isNotEmpty(featureMap)) {
//
//             double adViewCnt = Double.parseDouble(featureMap.getOrDefault("ad_view_cnt", "0"));
//             double adClick = Double.parseDouble(featureMap.getOrDefault("ad_click", "0"));
//             double adConver = Double.parseDouble(featureMap.getOrDefault("ad_conver", "0"));
//             double hasAdClick = Double.parseDouble(featureMap.getOrDefault("has_ad_click", "0"));
//             double hasAdShare = Double.parseDouble(featureMap.getOrDefault("has_ad_share", "0"));
//             double hasAdReturnCnt = Double.parseDouble(featureMap.getOrDefault("has_ad_return_cnt", "0"));
//             double noAdClick = Double.parseDouble(featureMap.getOrDefault("no_ad_click", "0"));
//             double noAdShare = Double.parseDouble(featureMap.getOrDefault("no_ad_share", "0"));
//             double noAdReturnCnt = Double.parseDouble(featureMap.getOrDefault("no_ad_return_cnt", "0"));
//
//             // 计算出回流出广告时的收益
//             double adClickValue = NumUtil.div(adClick, adViewCnt) * NumUtil.log10(adClick);
//             double adConverValue = NumUtil.div(adConver, adViewCnt) * NumUtil.log10(adConver);
//             double hasAdShareValue = NumUtil.div(hasAdShare, hasAdClick) * NumUtil.log10(hasAdShare);
//             double hasAdReturnValue = NumUtil.div(hasAdReturnCnt, hasAdClick) * NumUtil.log10(hasAdReturnCnt);
//             double hasAdValue = adClickValue + adConverValue + hasAdShareValue + hasAdReturnValue;
//
//             // 计算回流不出广告时的收益
//             double noAdShareValue = NumUtil.div(noAdShare, noAdClick) * NumUtil.log10(noAdShare);
//             double noAdReturnValue = NumUtil.div(noAdReturnCnt, noAdClick) * NumUtil.log10(noAdReturnCnt + hasAdReturnCnt);
//             double noAdValue = noAdShareValue + noAdReturnValue;
//
//             // 计算最终的收益
//             double hasRate = exp713Config.getOrDefault("hasRate", 1d);
//             double noRate = exp713Config.getOrDefault("noRate", 1d);
//             score = NumUtil.softmax(new double[]{hasAdValue * hasRate, noAdValue * noRate})[0];
//
//
//             ctx.getLogParam().getMetaFeature().putAll(feature.getUserFeature());
//             for (Map.Entry<String, String> entry : featureMap.entrySet()) {
//                 ctx.getLogParam().getAllFeature().put(entry.getKey(), Double.parseDouble(entry.getValue()));
//             }
//             ctx.getLogParam().getScoreMap().put("adClickValue", NumUtil.round(adClickValue, 6));
//             ctx.getLogParam().getScoreMap().put("adConverValue", NumUtil.round(adConverValue, 6));
//             ctx.getLogParam().getScoreMap().put("hasAdShareValue", NumUtil.round(hasAdShareValue, 6));
//             ctx.getLogParam().getScoreMap().put("hasAdReturnValue", NumUtil.round(hasAdReturnValue, 6));
//             ctx.getLogParam().getScoreMap().put("hasAdValue", NumUtil.round(hasAdValue, 6));
//             ctx.getLogParam().getScoreMap().put("noAdShareValue", NumUtil.round(noAdShareValue, 6));
//             ctx.getLogParam().getScoreMap().put("noAdReturnValue", NumUtil.round(noAdReturnValue, 6));
//             ctx.getLogParam().getScoreMap().put("noAdValue", NumUtil.round(noAdValue, 6));
//             ctx.getLogParam().getScoreMap().put("originScore", NumUtil.round(score, 6));
//             ctx.getLogParam().getScoreMap().put("hasRate", NumUtil.round(hasRate, 6));
//             ctx.getLogParam().getScoreMap().put("noRate", NumUtil.round(noRate, 6));
//
//             ctx.getLogParam().setBIsNewUser(false);
//         }
//
//         // 分数截断，避免过长或过短
//         if (score < minScore) {
//             score = minScore;
//         } else if (score > maxScore) {
//             score = maxScore;
//         }
//
//         double random = Math.random();
//         boolean isShowAd = random < score;
//         ctx.getLogParam().setExpId("713");
//         ctx.getLogParam().setScore(score);
//         ctx.getLogParam().getScoreMap().put("score", NumUtil.round(score, 6));
//         ctx.getLogParam().setAIsShowAd(isShowAd);
//         ctx.getLogParam().getScoreMap().put("minScore", minScore);
//         ctx.getLogParam().getScoreMap().put("maxScore", maxScore);
//         ctx.getLogParam().getScoreMap().put("random", random);
//
//
//         return isShowAd ? rtnAdPredict(ctx) : rtnNoAdPredict(ctx);
//     }
//
//
//     // public Map<String, Object> adPredictV1(PredictContext context){
//     //
//     //     Feature feature = featureService.getPredictFeature(context);
//     //     Map<String, Map<String, String>> userFeature = feature.getUserFeature();
//     //     Map<String, String> featureMap = userFeature.getOrDefault("alg_ad_crowd_choose_feature", new HashMap<>());
//     //
//     //     double score = -1;
//     //
//     //     // 没有特征为新用户，随机出广告
//     //     if (MapUtils.isEmpty(featureMap)) {
//     //         double newUserShowAdRate = exp713Config.getOrDefault("newUserShowAdRate", 0.8d);
//     //         double randomRate = Math.random();
//     //         if (randomRate < newUserShowAdRate) {
//     //             context.getLogParam().getScoreMap().put("newUserShowAdRate", newUserShowAdRate);
//     //             context.getLogParam().getScoreMap().put("randomRate", randomRate);
//     //             score = 1;
//     //         }
//     //     } else {
//     //         context.getLogParam().getMetaFeature().putAll(userFeature);
//     //         for (Map.Entry<String, String> entry : featureMap.entrySet()) {
//     //             context.getLogParam().getAllFeature().put(entry.getKey(), Double.parseDouble(entry.getValue()));
//     //         }
//     //
//     //         // 获取需要的特征值
//     //         double showAdClickPv = Double.parseDouble(featureMap.getOrDefault("show_ad_click_pv", "0"));
//     //         double noShowAdClickPv = Double.parseDouble(featureMap.getOrDefault("no_show_ad_click_pv", "0"));
//     //         double showAdIncome = Double.parseDouble(featureMap.getOrDefault("show_ad_income", "0"));
//     //         double showAdSharePv = Double.parseDouble(featureMap.getOrDefault("show_ad_share_pv", "0"));
//     //         double noShowAdSharePv = Double.parseDouble(featureMap.getOrDefault("no_show_ad_share_pv", "0"));
//     //         double showAdNewReturnPv = Double.parseDouble(featureMap.getOrDefault("show_ad_new_return_pv", "0"));
//     //         double noShowAdNewReturnPv = Double.parseDouble(featureMap.getOrDefault("no_show_ad_new_return_pv", "0"));
//     //
//     //         // 计算中间过程值
//     //         double singleReturnAdIncome = NumUtil.div(showAdIncome, (showAdClickPv + noShowAdClickPv));
//     //         double showAdShareRate = NumUtil.div((showAdSharePv + 1), (showAdClickPv + 1));
//     //         double noShowAdShareRate = NumUtil.div((noShowAdSharePv + 1), (noShowAdClickPv + 1));
//     //         double returnDivShare = NumUtil.div((showAdNewReturnPv + noShowAdNewReturnPv + 1), (showAdSharePv + noShowAdSharePv + 1));
//     //
//     //         double busDauBalanceRate = exp713Config.getOrDefault("busDauBalanceRate", 0.1d);
//     //         score = singleReturnAdIncome + ((showAdShareRate - noShowAdShareRate) * returnDivShare * busDauBalanceRate);
//     //
//     //
//     //         context.getLogParam().getScoreMap().put("singleReturnAdIncome", singleReturnAdIncome);
//     //         context.getLogParam().getScoreMap().put("showAdShareRate", showAdShareRate);
//     //         context.getLogParam().getScoreMap().put("noShowAdShareRate", noShowAdShareRate);
//     //         context.getLogParam().getScoreMap().put("returnDivShare", returnDivShare);
//     //         context.getLogParam().getScoreMap().put("busDauBalanceRate", busDauBalanceRate);
//     //
//     //     }
//     //     double showAdScoreThreshold = exp713Config.getOrDefault("showAdScoreThreshold", 0d);
//     //     boolean isShowAd = score >= showAdScoreThreshold;
//     //
//     //     context.getLogParam().setAIsShowAd(isShowAd);
//     //     context.getLogParam().setExpId("713");
//     //     context.getLogParam().setScore(score);
//     //     context.getLogParam().getScoreMap().put("score", score);
//     //     context.getLogParam().getScoreMap().put("showAdScoreThreshold", showAdScoreThreshold);
//     //
//     //
//     //     logHubService.crowdChooseLogUpload(context);
//     //
//     //
//     //     if (isShowAd) {
//     //         Map<String, Object> rtnMap = rtnAdPredict();
//     //         rtnMap.putAll(context.getLogParam().getScoreMap());
//     //         return rtnMap;
//     //     } else {
//     //         return rtnNoAdPredict("713_exp");
//     //     }
//     // }
// }
