package com.ytpm.middle.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ytpm.agent.model.YtApp;
import com.ytpm.agent.model.YtPlatformUserApp;
import com.ytpm.agent.param.AppListParam;
import com.ytpm.agent.param.AppParam;
import com.ytpm.agent.view.AgentAppView;
import com.ytpm.app.model.YtAppDefaultConfig;
import com.ytpm.app.view.WxDefaultConfig;
import com.ytpm.general.RepMessage;
import com.ytpm.general.Result;
import com.ytpm.general.ResultTable;
import com.ytpm.middle.dao.ApkMapper;
import com.ytpm.middle.dao.AppMapper;
import com.ytpm.middle.dao.RiskMapper;
import com.ytpm.middle.service.ApkService;
import com.ytpm.middle.util.AliOSSUtil;
import com.ytpm.middle.util.FeignClientInvoker;
import com.ytpm.middle.view.MiddleUserInfo;
import com.ytpm.risk.model.YtRiskConfig;
import com.ytpm.risk.model.YtRiskTemplate;
import com.ytpm.risk.model.YtRiskTemplateConfig;
import com.ytpm.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@RefreshScope
public class ApkServiceImpl implements ApkService {

    @Resource
    private ApkMapper apkMapper;
    @Resource
    private RiskMapper riskMapper;
    @Value("${risk.config.initEcpm}")
    private String initEcpm;
    @Value("${risk.config.initRevenue}")
    private String initRevenue;
    @Autowired
    private FeignClientInvoker feignInvoker;
    @Autowired
    private AppMapper appMapper;

    /**
     * 查询应用列表
     */
    @Override
    public ResultTable<AgentAppView> searchAppList(AppListParam appListParam) {
        PageHelper.startPage(appListParam.getPage(), appListParam.getLimit());
        List<AgentAppView> views = apkMapper.searchAppList(appListParam);
        String appIds = views.stream().map(AgentAppView::getAppId).collect(Collectors.joining(","));
        List<String> serviceList = views.stream().map(AgentAppView::getServiceName).distinct().collect(Collectors.toList());
        List<WxDefaultConfig> configs = new ArrayList<>();
        for (String serve : serviceList) {
           Object o = feignInvoker.invoke(serve, "getConfigs", appIds);
            if(Objects.isNull(o))continue;
            List<WxDefaultConfig> configList = JSONArray.parseArray(JSON.toJSONString(o), WxDefaultConfig.class);
            configs.addAll(configList);
        }
        Map<String, WxDefaultConfig> appTypeMap = configs.stream().collect(Collectors.toMap(WxDefaultConfig::getAppId, o->o));
        //分析OSS实时日志统计下载次数
        Map<String, Integer> countDownloadMap = AliOSSUtil.getCountDownload(
                Math.toIntExact(DateUtil.getTodayStart().getTime() / 1000), (int) (System.currentTimeMillis() / 1000));
        WxDefaultConfig config;
        for (AgentAppView view : views) {
            if(appTypeMap.containsKey(view.getAppId())) {
                config = appTypeMap.get(view.getAppId());
                view.setAppCode(config.getAppType());
                view.setDitchId(config.getDitchId());
                view.setTakuAppId(config.getTakuAppId());
                view.setTakuKey(config.getTakuKey());
                view.setTakuBannerPid(config.getTakuBannerPid());
                view.setTakuNativePid(config.getTakuNativePid());
                view.setTakuRewardPid(config.getTakuRewardPid());
                view.setTakuInterstitialPid(config.getTakuInterstitialPid());
                view.setCanUseRoot(config.getCanUseRoot());
                view.setCanUseAdb(config.getCanUseAdb());
                view.setCanUseFloat(config.getCanUseFloat());
                view.setCanAccumulation(config.getCanAccumulation());
                view.setCanSimulator(config.getCanSimulator());
                view.setPowerWaitTime(config.getPowerWaitTime());
                view.setInterstitialIntervalTime(config.getInterstitialIntervalTime());
            }
            if(CharSequenceUtil.isBlank(view.getApkUrl()))continue;
            String substring = view.getApkUrl().substring(view.getApkUrl().lastIndexOf("/")+1).toLowerCase(Locale.ENGLISH);
            if(countDownloadMap.containsKey(substring)){
                view.setDownloadCount(countDownloadMap.get(substring));
            }
        }
        return ResultTable.resultTableOk(new PageInfo<>(views));
    }

    /**
     * 新增应用
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> saveApp(AppParam param, MiddleUserInfo loginUser) {
        //数据库操作，有appId为修改， 没有时为新增
        changeDataAction(param,loginUser.getUserId());
        //出包修改 default_config
        changeDefaultConfig(param);
        if(CharSequenceUtil.isNotBlank(param.getAppId())){
            //修改时判断已生成风控配置，则说明出过包，仅需更换即可
            YtRiskTemplate template =  riskMapper.getTemplateByAppId(param.getAppId());
            if(Objects.isNull(template)){
                generateRiskDefaultConfig(param,loginUser);
            }
            return Result.resultOk(RepMessage.SAVE_SUCCESS);
        }
        return Result.resultOk(RepMessage.SAVE_SUCCESS);
    }

    /**
     * 修改子包配置
     */
    @Override
    public Result<?> changeConfig(AppParam param) {
        //出包修改 default_config
        changeDefaultConfig(param);
        return Result.resultOk(RepMessage.SAVE_SUCCESS);
    }

    /**
     * 出包修改对应子包的默认配置
     */
    private void changeDefaultConfig(AppParam param) {
        YtPlatformUserApp app = appMapper.getByPrimary(param.getSuperiorId());
        YtAppDefaultConfig config = new YtAppDefaultConfig();
        config.setAppId(param.getAppId());
        if(Objects.nonNull(param.getDitchId())){
            config.setDitchId(param.getDitchId().toString());
        }
        config.setTakuAppId(app.getTakuAppId());
        config.setTakuKey(app.getTakuKey());
        config.setTakuBannerPid(app.getTakuBannerPid());
        config.setTakuNativePid(app.getTakuNativePid());
        config.setTakuRewardPid(app.getTakuRewardPid());
        config.setTakuInterstitialPid(app.getTakuInterstitialPid());
        config.setCanAccumulation(param.getCanAccumulation());
        config.setCanUseAdb(param.getCanUseAdb());
        config.setCanUseFloat(param.getCanUseFloat());
        config.setCanUseRoot(param.getCanUseRoot());
        config.setPowerWaitTime(param.getPowerWaitTime());
        config.setInterstitialIntervalTime(param.getInterstitialIntervalTime());
        feignInvoker.invoke(app.getServiceName(), "updateAppConfig",config);
    }

    /**
     * 给应用生成默认的风控配置
     */
    private void generateRiskDefaultConfig(AppParam param,MiddleUserInfo loginUser) {
        addTemp742(param,loginUser);
        addTemp746(param,loginUser);
    }

    private void addTemp746(AppParam param, MiddleUserInfo loginUser) {
        String appId = param.getAppId();
        String agentId = param.getUserId();
        List<String> configIds = new ArrayList<>();
        String configId = IdUtil.getSnowflakeNextIdStr();
        configIds.add(configId);
        YtRiskConfig config = new YtRiskConfig(configId,agentId,"rewardCount","当日前2条获得奖励的激励视频",1,"2",2);
        riskMapper.insertConfigItem(config);
        configId = IdUtil.getSnowflakeNextIdStr();
        configIds.add(configId);
        config = new YtRiskConfig(configId,agentId,"income","总收益为<"+initRevenue,1,initRevenue,4);
        riskMapper.insertConfigItem(config);
        String templateId = IdUtil.getSnowflakeNextIdStr();
        YtRiskTemplateConfig templateConfig;
        for (String itemId : configIds) {
            templateConfig = new YtRiskTemplateConfig(templateId,itemId,loginUser.getUserId(),loginUser.getNickName(),new Date());
            riskMapper.insertTempConfig(templateConfig);
        }
        YtRiskTemplate template = new YtRiskTemplate(templateId,"最低收益限制",
                "当日前2条获得奖励的激励视频,总收益为<"+initRevenue,appId+"-746",agentId,
                2,appId,new Date(),loginUser.getUserId(),null,
                null,1,1,1);
        riskMapper.insertTemplate(template);
        //风控模版关联应用
        riskMapper.relativeApp(appId,param.getAppName(),template.getTemplateId(),
                loginUser.getNickName(),loginUser.getUserId());
    }

    private void addTemp742(AppParam param, MiddleUserInfo loginUser) {
        String appId = param.getAppId();
        String agentId = param.getUserId();
        List<String> configIds = new ArrayList<>();
        String configId = IdUtil.getSnowflakeNextIdStr();
        configIds.add(configId);
        YtRiskConfig config = new YtRiskConfig(configId,agentId,"firstAdCount","当日前4条激励视频",1,"4",2);
        riskMapper.insertConfigItem(config);
        configId = IdUtil.getSnowflakeNextIdStr();
        configIds.add(configId);
        config = new YtRiskConfig(configId,agentId,"haveCount","有2条",1,"2",2);
        riskMapper.insertConfigItem(config);
        configId = IdUtil.getSnowflakeNextIdStr();
        configIds.add(configId);
        config = new YtRiskConfig(configId,agentId,"ecpm","ecpm值为<"+initEcpm,1,initEcpm,4);
        riskMapper.insertConfigItem(config);
        String templateId = IdUtil.getSnowflakeNextIdStr();
        YtRiskTemplateConfig templateConfig;
        for (String itemId : configIds) {
            templateConfig = new YtRiskTemplateConfig(templateId,itemId,loginUser.getUserId(),loginUser.getNickName(),new Date());
            riskMapper.insertTempConfig(templateConfig);
        }
        YtRiskTemplate template = new YtRiskTemplate(templateId,"激励视频ecpm值控制",
                "当日前4条激励视频,有2条,ecpm值为<"+initEcpm,appId+"-742",agentId,
                2,appId,new Date(),loginUser.getUserId(),null,
                null,1,1,1);
        riskMapper.insertTemplate(template);
        //风控模版关联应用
        riskMapper.relativeApp(appId,param.getAppName(),template.getTemplateId(),
                loginUser.getNickName(),loginUser.getUserId());
    }

    /**
     * 处理数据库数据变更操作
     */
    private void changeDataAction(AppParam param, String userId) {
        YtApp app = new YtApp();
        BeanUtil.copyProperties(param, app);
        if(CharSequenceUtil.isNotBlank(param.getAppId())){
            apkMapper.updateOne(app);
        }else{
            app.setAppId(IdUtil.fastSimpleUUID());
            app.setUserId(userId);
            app.setEnabled(1);
            apkMapper.insertOne(app);
        }
    }
}
