import json
import time
import traceback
import datetime
from utils import RedisHelper
from config import set_config
from log import Log
from lr_model import get_final_score
log_ = Log()
config_ = set_config()
redis_helper = RedisHelper()


def get_params(ab_exp_info, ab_test_code):
    """
    根据实验分组给定对应的参数
    :param ab_exp_info: AB实验组参数
    :param ab_test_code: 用户对应的ab组
    :return:
    """
    abtest_id, abtest_config_tag = None, None
    ad_abtest_id_list = [key.split('-')[0] for key in config_.AD_ABTEST_CONFIG]
    # 获取广告实验配置
    config_value_dict = {}
    if ab_exp_info:
        ab_exp_list = ab_exp_info.get('ab_test002', None)
        if ab_exp_list:
            for ab_item in ab_exp_list:
                ab_exp_code = ab_item.get('abExpCode', None)
                if not ab_exp_code:
                    continue
                if ab_exp_code in ad_abtest_id_list:
                    config_value = ab_item.get('configValue', None)
                    if config_value:
                        config_value_dict[str(ab_exp_code)] = eval(str(config_value))

    if len(config_value_dict) > 0:
        for ab_exp_code, config_value in config_value_dict.items():
            for tag, value in config_value.items():
                if ab_test_code in value:
                    abtest_id = ab_exp_code
                    abtest_config_tag = tag
                    break

    return abtest_id, abtest_config_tag


def get_threshold(abtest_id, abtest_config_tag, ab_test_code, mid_group, care_model_status, abtest_param):
    """获取对应的阈值"""
    # 判断是否是关怀模式实验
    care_model_status_param = abtest_param.get('care_model_status_param', None)
    care_model_ab_mid_group = abtest_param.get('care_model_ab_mid_group', [])
    if care_model_status_param is None:
        # 无关怀模式实验
        threshold_key_name_prefix = config_.KEY_NAME_PREFIX_AD_THRESHOLD
    else:
        # 关怀模式实验
        if care_model_status is None or len(care_model_ab_mid_group) == 0 or care_model_status == 'null':
            # 参数缺失,走默认
            threshold_key_name_prefix = config_.KEY_NAME_PREFIX_AD_THRESHOLD
        elif int(care_model_status) == int(care_model_status_param) and mid_group in care_model_ab_mid_group:
            # 实验匹配,获取对应的阈值
            threshold_key_name_prefix = config_.KEY_NAME_PREFIX_AD_THRESHOLD_CARE_MODEL
        else:
            threshold_key_name_prefix = config_.KEY_NAME_PREFIX_AD_THRESHOLD

    threshold_key_name = f"{threshold_key_name_prefix}{abtest_id}:{abtest_config_tag}:{ab_test_code}:{mid_group}"
    threshold = redis_helper.get_data_from_redis(key_name=threshold_key_name)
    if threshold is None:
        threshold = 0
    else:
        threshold = float(threshold)
    return threshold


def predict_with_rate_process(now_date, video_id, abtest_param, abtest_id, abtest_config_tag, ab_test_code, care_model_status, mid_group):
    now_dt = datetime.datetime.strftime(now_date, '%Y%m%d')
    user_data_key = abtest_param['user'].get('data')
    user_rule_key = abtest_param['user'].get('rule')
    video_data_key = abtest_param['video'].get('data')
    # 获取用户组分享率
    group_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_GROUP}{user_data_key}:{user_rule_key}:{now_dt}"
    if not redis_helper.key_exists(group_share_rate_key):
        redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
        group_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_GROUP}{user_data_key}:{user_rule_key}:{redis_dt}"
    group_share_rate = redis_helper.get_score_with_value(key_name=group_share_rate_key, value=mid_group)
    # 获取视频分享率
    video_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{video_data_key}:{now_dt}"
    if not redis_helper.key_exists(video_share_rate_key):
        redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
        video_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{video_data_key}:{redis_dt}"
    video_share_rate = redis_helper.get_score_with_value(key_name=video_share_rate_key, value=int(video_id))
    if video_share_rate is None:
        video_share_rate = redis_helper.get_score_with_value(key_name=video_share_rate_key, value=-1)

    # 计算 mid-video 分享率
    if group_share_rate is None or video_share_rate is None:
        return None
    mid_video_predict_res = float(group_share_rate) * float(video_share_rate)

    # 获取对应的阈值
    threshold = get_threshold(
        abtest_id=abtest_id,
        abtest_config_tag=abtest_config_tag,
        ab_test_code=ab_test_code,
        mid_group=mid_group,
        care_model_status=care_model_status,
        abtest_param=abtest_param
    )
    # 阈值判断
    if mid_video_predict_res > threshold:
        # 大于阈值,出广告
        ad_predict = 2
    else:
        # 否则,不出广告
        ad_predict = 1
    result = {
        'mid_group': mid_group,
        'group_share_rate': group_share_rate,
        'video_share_rate': video_share_rate,
        'mid_video_predict_res': mid_video_predict_res,
        'threshold': threshold,
        'ad_predict': ad_predict
    }
    return result


def predict_mid_video_res(now_date, mid, video_id, abtest_param, abtest_id, abtest_config_tag, ab_test_code, care_model_status, app_type):
    # now_dt = datetime.datetime.strftime(now_date, '%Y%m%d')
    # user_data_key = abtest_param['user'].get('data')
    # user_rule_key = abtest_param['user'].get('rule')
    # video_data_key = abtest_param['video'].get('data')
    group_class_key = abtest_param.get('group_class_key')
    no_ad_mid_group_list = abtest_param.get('no_ad_mid_group_list', [])
    no_ad_group_with_video_mapping = abtest_param.get('no_ad_group_with_video_mapping', {})

    # 判断mid所属分组
    mid_group_key_name = f"{config_.KEY_NAME_PREFIX_MID_GROUP}{group_class_key}:{mid}"
    mid_group = redis_helper.get_data_from_redis(key_name=mid_group_key_name)
    if mid_group is None:
        mid_group = 'mean_group'

    # 判断用户是否在免广告用户组列表中
    if mid_group in no_ad_mid_group_list:
        # 在免广告用户组列表中,则不出广告
        ad_predict = 1
        result = {
            'mid_group': mid_group,
            'ad_predict': ad_predict,
            'no_ad_strategy': 'no_ad_mid_group'
        }
    elif mid_group in no_ad_group_with_video_mapping:
        # 用户组在特定内容不出广告设置中
        # 获取对应的特定内容
        video_mapping_key_list = no_ad_group_with_video_mapping.get(mid_group, [])
        no_ad_videos = redis_helper.get_data_from_redis(key_name=f"{config_.KEY_NAME_PREFIX_NO_AD_VIDEOS}{app_type}")
        if no_ad_videos is not None:
            no_ad_videos = json.loads(no_ad_videos)
        else:
            no_ad_videos = {}
        no_ad_video_list = []
        for video_mapping_key in video_mapping_key_list:
            no_ad_video_list.extend(no_ad_videos.get(video_mapping_key, []))
        # 判断此次请求视频是否在免广告视频列表中
        if video_id in no_ad_video_list:
            # 在,则不出广告
            ad_predict = 1
            result = {
                'mid_group': mid_group,
                'ad_predict': ad_predict,
                'no_ad_strategy': 'no_ad_mid_group_with_video'
            }
        else:
            result = predict_with_rate_process(
                now_date=now_date,
                video_id=video_id,
                abtest_param=abtest_param,
                abtest_id=abtest_id,
                abtest_config_tag=abtest_config_tag,
                ab_test_code=ab_test_code,
                care_model_status=care_model_status,
                mid_group=mid_group)

    else:
        result = predict_with_rate_process(
            now_date=now_date,
            video_id=video_id,
            abtest_param=abtest_param,
            abtest_id=abtest_id,
            abtest_config_tag=abtest_config_tag,
            ab_test_code=ab_test_code,
            care_model_status=care_model_status,
            mid_group=mid_group)

    return result


def predict_mid_video_res_with_add(now_date, mid, video_id, abtest_param, abtest_id, abtest_config_tag, ab_test_code, care_model_status):
    now_dt = datetime.datetime.strftime(now_date, '%Y%m%d')

    # 判断mid所属分组
    group_class_key = abtest_param.get('group_class_key')
    mid_group_key_name = f"{config_.KEY_NAME_PREFIX_MID_GROUP}{group_class_key}:{mid}"
    mid_group = redis_helper.get_data_from_redis(key_name=mid_group_key_name)
    if mid_group is None:
        mid_group = 'mean_group'

    # 判断用户是否在免广告用户组列表中
    no_ad_mid_group_list = abtest_param.get('no_ad_mid_group_list', [])
    if mid_group in no_ad_mid_group_list:
        # 在免广告用户组列表中,则不出广告
        ad_predict = 1
        result = {
            'mid_group': mid_group,
            'ad_predict': ad_predict
        }
    else:
        # 获取用户组出广告后分享的概率
        share_user_data_key = abtest_param['share']['user'].get('data')
        share_user_rule_key = abtest_param['share']['user'].get('rule')
        group_share_rate_key = \
            f"{config_.KEY_NAME_PREFIX_AD_GROUP}{share_user_data_key}:{share_user_rule_key}:{now_dt}"
        if not redis_helper.key_exists(group_share_rate_key):
            redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
            group_share_rate_key = \
                f"{config_.KEY_NAME_PREFIX_AD_GROUP}{share_user_data_key}:{share_user_rule_key}:{redis_dt}"
        group_share_rate = redis_helper.get_score_with_value(key_name=group_share_rate_key, value=mid_group)

        # 获取视频出广告后分享的概率
        share_video_data_key = abtest_param['share']['video'].get('data')
        video_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{share_video_data_key}:{now_dt}"
        if not redis_helper.key_exists(video_share_rate_key):
            redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
            video_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{share_video_data_key}:{redis_dt}"
        video_share_rate = redis_helper.get_score_with_value(key_name=video_share_rate_key, value=int(video_id))
        if video_share_rate is None:
            video_share_rate = redis_helper.get_score_with_value(key_name=video_share_rate_key, value=-1)

        # 获取用户组出广告后不直接跳出的概率
        out_user_data_key = abtest_param['out']['user'].get('data')
        out_user_rule_key = abtest_param['out']['user'].get('rule')
        group_out_rate_key = \
            f"{config_.KEY_NAME_PREFIX_AD_GROUP}{out_user_data_key}:{out_user_rule_key}:{now_dt}"
        if not redis_helper.key_exists(group_out_rate_key):
            redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
            group_out_rate_key = \
                f"{config_.KEY_NAME_PREFIX_AD_GROUP}{out_user_data_key}:{out_user_rule_key}:{redis_dt}"
        group_out_rate = redis_helper.get_score_with_value(key_name=group_out_rate_key, value=mid_group)

        # 获取视频出广告后不直接跳出的概率
        out_video_data_key = abtest_param['out']['video'].get('data')
        video_out_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{out_video_data_key}:{now_dt}"
        if not redis_helper.key_exists(video_out_rate_key):
            redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
            video_out_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{out_video_data_key}:{redis_dt}"
        video_out_rate = redis_helper.get_score_with_value(key_name=video_out_rate_key, value=int(video_id))
        if video_out_rate is None:
            video_out_rate = redis_helper.get_score_with_value(key_name=video_out_rate_key, value=-1)

        # 计算 mid-video 预测值
        if group_share_rate is None or video_share_rate is None or group_out_rate is None or video_out_rate is None:
            return None
        # 加权融合
        share_weight = abtest_param['mix_param']['share_weight']
        out_weight = abtest_param['mix_param']['out_weight']
        group_rate = share_weight * float(group_share_rate) + out_weight * float(group_out_rate)
        video_rate = share_weight * float(video_share_rate) + out_weight * float(video_out_rate)
        mid_video_predict_res = group_rate * video_rate

        # 获取对应的阈值
        threshold = get_threshold(
            abtest_id=abtest_id,
            abtest_config_tag=abtest_config_tag,
            ab_test_code=ab_test_code,
            mid_group=mid_group,
            care_model_status=care_model_status,
            abtest_param=abtest_param
        )
        # 阈值判断
        if mid_video_predict_res > threshold:
            # 大于阈值,出广告
            ad_predict = 2
        else:
            # 否则,不出广告
            ad_predict = 1
        result = {
            'mid_group': mid_group,
            'group_share_rate': group_share_rate,
            'video_share_rate': video_share_rate,
            'group_out_rate': group_out_rate,
            'video_out_rate': video_out_rate,
            'group_rate': group_rate,
            'video_rate': video_rate,
            'mid_video_predict_res': mid_video_predict_res,
            'threshold': threshold,
            'ad_predict': ad_predict}
    return result

def predict_mid_video_res_with_model(now_date, mid, video_id, abtest_param, abtest_id, abtest_config_tag, ab_test_code, care_model_status, app_type):

    model_key = abtest_param.get('model_key', 'ad_out_v1')
    user_key_name = f"{config_.KEY_NAME_PREFIX_AD_OUT_MODEL_SCORE_USER}{model_key}:{mid}"
    item_key_name = f"{config_.KEY_NAME_PREFIX_AD_OUT_MODEL_SCORE_ITEM}{model_key}:{video_id}"
    config_key_prefix = f"{config_.KEY_NAME_PREFIX_AD_OUT_MODEL_CONFIG}{model_key}:{abtest_id}:{abtest_config_tag}"
    threshold_key = f"{config_key_prefix}:threshold"

    user_score = redis_helper.get_data_from_redis(key_name=user_key_name)
    item_score = redis_helper.get_data_from_redis(key_name=item_key_name)

    # 如果离线分数为空,则走基线逻辑
    if user_score is None or item_score is None:
        result = predict_mid_video_res(
            now_date=now_date,
            mid=mid,
            video_id=video_id,
            abtest_param=abtest_param,
            abtest_id=abtest_id,
            abtest_config_tag=abtest_config_tag,
            ab_test_code=ab_test_code,
            care_model_status=care_model_status,
            app_type=app_type
        )
        return result

    offline_score = float(user_score) + float(item_score)
    online_features = {
        'ctx_apptype': str(app_type),
        'ctx_week': time.strftime('%w', time.localtime()),
        'ctx_hour':  time.strftime('%H', time.localtime()),
    }

    final_score, online_score = get_final_score(online_features, offline_score)
    threshold = float(redis_helper.get_data_from_redis(key_name=threshold_key))

    # 跳出率阈值判断
    if final_score < threshold:
        # 小于阈值,出广告
        ad_predict = 2
    else:
        # 否则,不出广告
        ad_predict = 1
    result = {
        'user_score': user_score,
        'item_score': item_score,
        'final_score': final_score,
        'online_score': online_score,
        'threshold': threshold,
        'ad_predict': ad_predict,
        'online_features': online_features,
    }
    return result

def predict_mid_video_res_with_multiply(now_date, mid, video_id, abtest_param, abtest_id, abtest_config_tag, ab_test_code, care_model_status):
    now_dt = datetime.datetime.strftime(now_date, '%Y%m%d')

    # 判断mid所属分组
    group_class_key = abtest_param.get('group_class_key')
    mid_group_key_name = f"{config_.KEY_NAME_PREFIX_MID_GROUP}{group_class_key}:{mid}"
    mid_group = redis_helper.get_data_from_redis(key_name=mid_group_key_name)
    if mid_group is None:
        mid_group = 'mean_group'

    # 判断用户是否在免广告用户组列表中
    no_ad_mid_group_list = abtest_param.get('no_ad_mid_group_list', [])
    if mid_group in no_ad_mid_group_list:
        # 在免广告用户组列表中,则不出广告
        ad_predict = 1
        result = {
            'mid_group': mid_group,
            'ad_predict': ad_predict
        }
    else:
        # 获取用户组出广告后分享的概率
        share_user_data_key = abtest_param['share']['user'].get('data')
        share_user_rule_key = abtest_param['share']['user'].get('rule')
        group_share_rate_key = \
            f"{config_.KEY_NAME_PREFIX_AD_GROUP}{share_user_data_key}:{share_user_rule_key}:{now_dt}"
        if not redis_helper.key_exists(group_share_rate_key):
            redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
            group_share_rate_key = \
                f"{config_.KEY_NAME_PREFIX_AD_GROUP}{share_user_data_key}:{share_user_rule_key}:{redis_dt}"
        group_share_rate = redis_helper.get_score_with_value(key_name=group_share_rate_key, value=mid_group)

        # 获取视频出广告后分享的概率
        share_video_data_key = abtest_param['share']['video'].get('data')
        video_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{share_video_data_key}:{now_dt}"
        if not redis_helper.key_exists(video_share_rate_key):
            redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
            video_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{share_video_data_key}:{redis_dt}"
        video_share_rate = redis_helper.get_score_with_value(key_name=video_share_rate_key, value=int(video_id))
        if video_share_rate is None:
            video_share_rate = redis_helper.get_score_with_value(key_name=video_share_rate_key, value=-1)

        # 获取用户组出广告后不直接跳出的概率
        out_user_data_key = abtest_param['out']['user'].get('data')
        out_user_rule_key = abtest_param['out']['user'].get('rule')
        group_out_rate_key = \
            f"{config_.KEY_NAME_PREFIX_AD_GROUP}{out_user_data_key}:{out_user_rule_key}:{now_dt}"
        if not redis_helper.key_exists(group_out_rate_key):
            redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
            group_out_rate_key = \
                f"{config_.KEY_NAME_PREFIX_AD_GROUP}{out_user_data_key}:{out_user_rule_key}:{redis_dt}"
        group_out_rate = redis_helper.get_score_with_value(key_name=group_out_rate_key, value=mid_group)

        # 获取视频出广告后不直接跳出的概率
        out_video_data_key = abtest_param['out']['video'].get('data')
        video_out_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{out_video_data_key}:{now_dt}"
        if not redis_helper.key_exists(video_out_rate_key):
            redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
            video_out_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{out_video_data_key}:{redis_dt}"
        video_out_rate = redis_helper.get_score_with_value(key_name=video_out_rate_key, value=int(video_id))
        if video_out_rate is None:
            video_out_rate = redis_helper.get_score_with_value(key_name=video_out_rate_key, value=-1)

        # 计算 mid-video 预测值
        if group_share_rate is None or video_share_rate is None or group_out_rate is None or video_out_rate is None:
            return None
        # 乘积融合
        group_rate = float(group_share_rate) * float(group_out_rate)
        video_rate = float(video_share_rate) * float(video_out_rate)
        mid_video_predict_res = group_rate * video_rate

        # 获取对应的阈值
        threshold = get_threshold(
            abtest_id=abtest_id,
            abtest_config_tag=abtest_config_tag,
            ab_test_code=ab_test_code,
            mid_group=mid_group,
            care_model_status=care_model_status,
            abtest_param=abtest_param
        )
        # 阈值判断
        if mid_video_predict_res > threshold:
            # 大于阈值,出广告
            ad_predict = 2
        else:
            # 否则,不出广告
            ad_predict = 1
        result = {
            'mid_group': mid_group,
            'group_share_rate': group_share_rate,
            'video_share_rate': video_share_rate,
            'group_out_rate': group_out_rate,
            'video_out_rate': video_out_rate,
            'group_rate': group_rate,
            'video_rate': video_rate,
            'mid_video_predict_res': mid_video_predict_res,
            'threshold': threshold,
            'ad_predict': ad_predict}
    return result


def ad_recommend_predict(app_type, mid, video_id, ab_exp_info, ab_test_code, care_model_status):
    """
    广告推荐预测
    :param app_type: app_type
    :param mid: mid
    :param video_id: video_id
    :param ab_exp_info: AB实验组参数
    :param ab_test_code: 用户对应的ab组
    :param care_model_status: 用户关怀模式状态 1-未开启,2-开启
    :return: ad_predict, type-int, 1-不发放广告,2-发放广告
    """
    try:
        now_date = datetime.datetime.today()
        # now_dt = datetime.datetime.strftime(now_date, '%Y%m%d')
        now_h = datetime.datetime.now().hour
        if 0 <= now_h < 8:
            # 00:00 - 08:00 不出广告
            ad_predict = 1
            result = {
                'now_h': now_h,
                'ad_predict': ad_predict
            }
            return result
        # 获取实验参数
        abtest_id, abtest_config_tag = get_params(ab_exp_info=ab_exp_info, ab_test_code=ab_test_code)
        if abtest_id is None or abtest_config_tag is None:
            return None
        abtest_param = config_.AD_ABTEST_CONFIG.get(f'{abtest_id}-{abtest_config_tag}')
        if abtest_param is None:
            return None

        threshold_mix_func = abtest_param.get('threshold_mix_func', None)
        if threshold_mix_func == 'add':
            result = predict_mid_video_res_with_add(
                now_date=now_date,
                mid=mid,
                video_id=video_id,
                abtest_param=abtest_param,
                abtest_id=abtest_id,
                abtest_config_tag=abtest_config_tag,
                ab_test_code=ab_test_code,
                care_model_status=care_model_status
            )
        elif threshold_mix_func == 'multiply':
            result = predict_mid_video_res_with_multiply(
                now_date=now_date,
                mid=mid,
                video_id=video_id,
                abtest_param=abtest_param,
                abtest_id=abtest_id,
                abtest_config_tag=abtest_config_tag,
                ab_test_code=ab_test_code,
                care_model_status=care_model_status
            )
        elif threshold_mix_func == 'model':
            result = predict_mid_video_res_with_model(
                now_date=now_date,
                mid=mid,
                video_id=video_id,
                abtest_param=abtest_param,
                abtest_id=abtest_id,
                abtest_config_tag=abtest_config_tag,
                ab_test_code=ab_test_code,
                care_model_status=care_model_status,
                app_type=app_type
            )
        else:
            result = predict_mid_video_res(
                now_date=now_date,
                mid=mid,
                video_id=video_id,
                abtest_param=abtest_param,
                abtest_id=abtest_id,
                abtest_config_tag=abtest_config_tag,
                ab_test_code=ab_test_code,
                care_model_status=care_model_status,
                app_type=app_type
            )

        # user_data_key = abtest_param['user'].get('data')
        # user_rule_key = abtest_param['user'].get('rule')
        # video_data_key = abtest_param['video'].get('data')
        # group_class_key = abtest_param.get('group_class_key')
        # no_ad_mid_group_list = abtest_param.get('no_ad_mid_group_list', [])
        #
        # # 判断mid所属分组
        # mid_group_key_name = f"{config_.KEY_NAME_PREFIX_MID_GROUP}{group_class_key}:{mid}"
        # mid_group = redis_helper.get_data_from_redis(key_name=mid_group_key_name)
        # if mid_group is None:
        #     mid_group = 'mean_group'
        #
        # # 判断用户是否在免广告用户组列表中
        # if mid_group in no_ad_mid_group_list:
        #     # 在免广告用户组列表中,则不出广告
        #     ad_predict = 1
        #     result = {
        #         'mid_group': mid_group,
        #         'ad_predict': ad_predict
        #     }
        # else:
        #     # 获取用户组分享率
        #     group_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_GROUP}{user_data_key}:{user_rule_key}:{now_dt}"
        #     if not redis_helper.key_exists(group_share_rate_key):
        #         redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
        #         group_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_GROUP}{user_data_key}:{user_rule_key}:{redis_dt}"
        #     group_share_rate = redis_helper.get_score_with_value(key_name=group_share_rate_key, value=mid_group)
        #     # 获取视频分享率
        #     video_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{video_data_key}:{now_dt}"
        #     if not redis_helper.key_exists(video_share_rate_key):
        #         redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
        #         video_share_rate_key = f"{config_.KEY_NAME_PREFIX_AD_VIDEO}{video_data_key}:{redis_dt}"
        #     video_share_rate = redis_helper.get_score_with_value(key_name=video_share_rate_key, value=int(video_id))
        #     if video_share_rate is None:
        #         video_share_rate = redis_helper.get_score_with_value(key_name=video_share_rate_key, value=-1)
        #
        #     # 计算 mid-video 分享率
        #     if group_share_rate is None or video_share_rate is None:
        #         return None
        #     mid_video_share_rate = float(group_share_rate) * float(video_share_rate)
        #
        #     # 获取对应的阈值
        #     threshold = get_threshold(
        #         abtest_id=abtest_id,
        #         abtest_config_tag=abtest_config_tag,
        #         ab_test_code=ab_test_code,
        #         mid_group=mid_group,
        #         care_model_status=care_model_status,
        #         abtest_param=abtest_param
        #     )
        #     # 阈值判断
        #     if mid_video_share_rate > threshold:
        #         # 大于阈值,出广告
        #         ad_predict = 2
        #     else:
        #         # 否则,不出广告
        #         ad_predict = 1
        #     result = {
        #         'mid_group': mid_group,
        #         'group_share_rate': group_share_rate,
        #         'video_share_rate': video_share_rate,
        #         'mid_video_share_rate': mid_video_share_rate,
        #         'threshold': threshold,
        #         'ad_predict': ad_predict}

        return result

    except Exception as e:
        log_.error(traceback.format_exc())
        return None


def ad_recommend_predict_with_roi(app_type, mid, video_id, ads, arpu, roi_param):
    """
    广告推荐预测
    :param app_type: app_type
    :param mid: mid
    :param video_id: video_id
    :param ads: 需要发放广告列表 list
    :param arpu: 上一周期arpu值
    :param roi_param: 计算roi使用参数
    :return: ad_predict, type-int, 1-不发放广告,2-发放广告
    """
    try:
        now_date = datetime.datetime.today()
        now_dt = datetime.datetime.strftime(now_date, '%Y%m%d')
        ad_info = ads[0]
        ad_id = ad_info['adId']
        ad_type = ad_info['adType']
        ecpm = float(ad_info['ecpm'])

        # 获取参数
        params = config_.PARAMS_NEW_STRATEGY[int(app_type)]
        # 判断mid所属分组
        group_class_key = params.get('group_class_key')
        mid_group_key_name = f"{config_.KEY_NAME_PREFIX_MID_GROUP}{group_class_key}:{mid}"
        mid_group = redis_helper.get_data_from_redis(key_name=mid_group_key_name)
        if mid_group is None:
            mid_group = 'mean_group'

        # 获取用户组出广告后分享的概率
        share_user_data_key = params['user'].get('data')
        share_user_rule_key = params['user'].get('rule')
        group_share_rate_key_with_ad = \
            f"{config_.KEY_NAME_PREFIX_GROUP_WITH_AD}{share_user_data_key}:{share_user_rule_key}:{now_dt}"
        if not redis_helper.key_exists(group_share_rate_key_with_ad):
            redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
            group_share_rate_key_with_ad = \
                f"{config_.KEY_NAME_PREFIX_GROUP_WITH_AD}{share_user_data_key}:{share_user_rule_key}:{redis_dt}"
        group_share_rate_with_ad = redis_helper.get_score_with_value(key_name=group_share_rate_key_with_ad,
                                                                     value=mid_group)

        # 获取视频出广告后分享的概率
        share_video_data_key = params['video'].get('data')
        video_share_rate_key_with_ad = f"{config_.KEY_NAME_PREFIX_VIDEO_WITH_AD}{share_video_data_key}:{now_dt}"
        if not redis_helper.key_exists(video_share_rate_key_with_ad):
            redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
            video_share_rate_key_with_ad = f"{config_.KEY_NAME_PREFIX_VIDEO_WITH_AD}{share_video_data_key}:{redis_dt}"
        video_share_rate_with_ad = redis_helper.get_score_with_value(key_name=video_share_rate_key_with_ad,
                                                                     value=int(video_id))
        if video_share_rate_with_ad is None:
            video_share_rate_with_ad = redis_helper.get_score_with_value(key_name=video_share_rate_key_with_ad,
                                                                         value=-1)

        # 获取用户组不出广告后分享的概率
        group_share_rate_key_no_ad = \
            f"{config_.KEY_NAME_PREFIX_GROUP_NO_AD}{share_user_data_key}:{share_user_rule_key}:{now_dt}"
        if not redis_helper.key_exists(group_share_rate_key_no_ad):
            redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
            group_share_rate_key_no_ad = \
                f"{config_.KEY_NAME_PREFIX_GROUP_NO_AD}{share_user_data_key}:{share_user_rule_key}:{redis_dt}"
        group_share_rate_no_ad = redis_helper.get_score_with_value(key_name=group_share_rate_key_no_ad, value=mid_group)

        # 获取视频不出广告后分享的概率
        video_share_rate_key_no_ad = f"{config_.KEY_NAME_PREFIX_VIDEO_NO_AD}{share_video_data_key}:{now_dt}"
        if not redis_helper.key_exists(video_share_rate_key_no_ad):
            redis_dt = datetime.datetime.strftime(now_date - datetime.timedelta(days=1), '%Y%m%d')
            video_share_rate_key_no_ad = f"{config_.KEY_NAME_PREFIX_VIDEO_NO_AD}{share_video_data_key}:{redis_dt}"
        video_share_rate_no_ad = redis_helper.get_score_with_value(key_name=video_share_rate_key_no_ad,
                                                                   value=int(video_id))
        if video_share_rate_no_ad is None:
            video_share_rate_no_ad = redis_helper.get_score_with_value(key_name=video_share_rate_key_no_ad, value=-1)

        if group_share_rate_with_ad is None or video_share_rate_with_ad is None \
                or group_share_rate_no_ad is None or video_share_rate_no_ad is None:
            return None
        # 计算此次请求出广告后分享的概率
        share_rate_with_ad = float(group_share_rate_with_ad) * float(video_share_rate_with_ad)
        # 计算此次请求不出广告分享的概率
        share_rate_no_ad = float(group_share_rate_no_ad) * float(video_share_rate_no_ad)
        # 计算此次请求出广告的收入增益
        roi_ad = ecpm / 1000 - float(roi_param) * float(arpu) * (share_rate_no_ad - share_rate_with_ad)
        # 收入增益判断
        if roi_ad > 0:
            # 大于0,出广告
            ad_predict = 2
        else:
            # 否则,不出广告
            ad_predict = 1
        result = {
            'arpu': arpu,
            'roi_param': roi_param,
            'ad_id': ad_id,
            'ad_type': ad_type,
            'mid_group': mid_group,
            'group_share_rate_with_ad': group_share_rate_with_ad,
            'video_share_rate_with_ad': video_share_rate_with_ad,
            'group_share_rate_no_ad': group_share_rate_no_ad,
            'video_share_rate_no_ad': video_share_rate_no_ad,
            'share_rate_with_ad': share_rate_with_ad,
            'share_rate_no_ad': share_rate_no_ad,
            'roi_ad': roi_ad,
            'ad_predict': ad_predict
        }
        return result

    except Exception as e:
        log_.error(traceback.format_exc())
        return None