package com.tzld.piaoquan.ad.engine.service.predict.model.threshold;

import com.tzld.piaoquan.ad.engine.commons.enums.AppTypeEnum;
import com.tzld.piaoquan.ad.engine.commons.redis.AlgorithmRedisHelper;
import com.tzld.piaoquan.ad.engine.service.predict.config.RoiModelConfig;
import com.tzld.piaoquan.ad.engine.service.predict.constant.RuleRedisKeyConst;
import com.tzld.piaoquan.ad.engine.service.predict.container.RoiPredictParamContainer;
import com.tzld.piaoquan.ad.engine.service.predict.param.RoiThresholdPredictModelParam;
import com.tzld.piaoquan.ad.engine.service.predict.helper.RuleParamHelper;
import com.tzld.piaoquan.ad.engine.service.predict.param.ThresholdPredictModelParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Component
public class RoiThresholdPredictModel extends ThresholdPredictModel{

    @Autowired
    RuleParamHelper paramHelper;

    @Autowired
    AlgorithmRedisHelper redisHelper;

    @Override
    String initName() {
        return "roi";
    }

    @Autowired
    RoiPredictParamContainer container;

    @Autowired
    RoiModelConfig roiModelConfig;
    @Override
    public <T extends ThresholdPredictModelParam> Map<String, Object> predict(T param) {

        RoiThresholdPredictModelParam modelParam=(RoiThresholdPredictModelParam)param;
        Date previousDate = new Date(modelParam.getDate().getTime() - (24 * 60 * 60 * 1000)); // Subtract one day
        String nowDt = new SimpleDateFormat("yyyyMMdd").format(modelParam.getDate());
        String previousDt = new SimpleDateFormat("yyyyMMdd").format(previousDate);


        Map<String, Object> userParams =( Map<String, Object>) ((Map<String,Object>)roiModelConfig.get(AppTypeEnum.valueOf(modelParam.getAppType()).name())).get("user");
        String shareUserDataKey = (String) userParams.get("data");
        String shareUserRuleKey = (String) userParams.get("rule");

        String groupShareRateKeyWithAd = RuleRedisKeyConst.KEY_NAME_PREFIX_GROUP_WITH_AD + shareUserDataKey + ":" + shareUserRuleKey + ":" + nowDt;
        if (!redisHelper.containsKey(groupShareRateKeyWithAd)) {
            groupShareRateKeyWithAd = RuleRedisKeyConst.KEY_NAME_PREFIX_GROUP_WITH_AD + shareUserDataKey + ":" + shareUserRuleKey + ":" + previousDt;
        }
        Double groupShareRateWithAd = redisHelper.zScore(groupShareRateKeyWithAd, modelParam.getMid());

        Map<String, Object> videoParams = ( Map<String, Object>) ((Map<String,Object>)roiModelConfig.get(AppTypeEnum.valueOf(modelParam.getAppType()).name())).get("video");
        String shareVideoDataKey = (String) videoParams.get("data");
        String videoShareRateKeyWithAd = RuleRedisKeyConst.KEY_NAME_PREFIX_VIDEO_WITH_AD + shareVideoDataKey + ":" + nowDt;
        if (!redisHelper.containsKey(videoShareRateKeyWithAd)) {
            videoShareRateKeyWithAd = RuleRedisKeyConst.KEY_NAME_PREFIX_VIDEO_WITH_AD + shareVideoDataKey + ":" + previousDt;
        }
        Double videoShareRateWithAd = redisHelper.zScore(videoShareRateKeyWithAd,modelParam.getVideoId().toString());
        if (videoShareRateWithAd == null) {
            videoShareRateWithAd = redisHelper.zScore(videoShareRateKeyWithAd, -1+"");
        }

        String groupShareRateKeyNoAd = RuleRedisKeyConst.KEY_NAME_PREFIX_GROUP_NO_AD + shareUserDataKey + ":" + shareUserRuleKey + ":" + nowDt;
        if (!redisHelper.containsKey(groupShareRateKeyNoAd)) {
            groupShareRateKeyNoAd = RuleRedisKeyConst.KEY_NAME_PREFIX_GROUP_NO_AD + shareUserDataKey + ":" + shareUserRuleKey + ":" + previousDt;
        }
        Double groupShareRateNoAd = redisHelper.zScore(groupShareRateKeyNoAd, modelParam.getMidGroup());

        String videoShareRateKeyNoAd = RuleRedisKeyConst.KEY_NAME_PREFIX_VIDEO_NO_AD + shareVideoDataKey + ":" + nowDt;
        if (!redisHelper.containsKey(videoShareRateKeyNoAd)) {
            videoShareRateKeyNoAd = RuleRedisKeyConst.KEY_NAME_PREFIX_VIDEO_NO_AD + shareVideoDataKey + ":" + previousDt;
        }
        Double videoShareRateNoAd = redisHelper.zScore(videoShareRateKeyNoAd,modelParam.getVideoId().toString());
        if (videoShareRateNoAd == null) {
            videoShareRateNoAd = redisHelper.zScore(videoShareRateKeyNoAd, -1+"");
        }

        if (groupShareRateWithAd == null || videoShareRateWithAd == null || groupShareRateNoAd == null || videoShareRateNoAd == null) {
            return new HashMap<>();
        }

        Double shareRateWithAd = groupShareRateWithAd * videoShareRateWithAd;
        Double shareRateNoAd = groupShareRateNoAd * videoShareRateNoAd;

        Double roiAd = (modelParam.getEcpm() / 1000d) - (container.getAdRoi() * container.getAdArpu() * (shareRateNoAd - shareRateWithAd));
        Double adPredict=roiAd>0?2d:1d;
        Map<String, Object> result = new HashMap<>();
        result.put("arpu", container.getAdArpu());
        result.put("roi_param", container.getAdRoi());
        result.put("ad_id", modelParam.getAdId());
        result.put("ad_type",  modelParam.getAdType());
        result.put("mid_group", modelParam.getMidGroup());
        result.put("group_share_rate_with_ad", groupShareRateWithAd);
        result.put("video_share_rate_with_ad", videoShareRateWithAd);
        result.put("group_share_rate_no_ad", groupShareRateNoAd);
        result.put("video_share_rate_no_ad", videoShareRateNoAd);
        result.put("share_rate_with_ad", shareRateWithAd);
        result.put("share_rate_no_ad", shareRateNoAd);
        result.put("roi_ad", roiAd);
        result.put("ad_predict", adPredict);
        return result;
    }
}
