package com.ruixuan.launch.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruixuan.common.core.domain.ResultResponse;
import com.ruixuan.common.utils.Check;
import com.ruixuan.common.utils.DateUtils;
import com.ruixuan.common.utils.RedisUtil;
import com.ruixuan.launch.entity.AccountToken;
import com.ruixuan.launch.entity.KuaishouLaunchCampaign;
import com.ruixuan.launch.entity.KuaishouLaunchCampaignAutoStrategy;
import com.ruixuan.launch.entity.KuaishouLaunchTargetTemplate;
import com.ruixuan.launch.mapper.KuaishouLaunchCampaignAutoStrategyMapper;
import com.ruixuan.launch.service.IAccountTokenService;
import com.ruixuan.launch.service.IKuaishouLaunchCampaignAutoStrategyService;
import com.ruixuan.launch.service.IKuaishouLaunchCampaignService;
import com.ruixuan.launch.service.IKuaishouLaunchCreativeService;
import com.ruixuan.launch.service.IKuaishouLaunchGroupService;
import com.ruixuan.launch.service.IKuaishouLaunchTargetTemplateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;

/**
 * 投流策略Service业务层处理
 *
 * @author ruoyi
 * @date 2022-07-05
 */
@Slf4j
@Service
public class KuaishouLaunchCampaignAutoStrategyServiceImpl implements IKuaishouLaunchCampaignAutoStrategyService {
    @Autowired
    private KuaishouLaunchCampaignAutoStrategyMapper kuaishouLaunchCampaignAutoStrategyMapper;

    @Autowired
    private IKuaishouLaunchCampaignService kuaishouLaunchCampaignService;

    @Autowired
    private IKuaishouLaunchCreativeService kuaishouLaunchCreativeService;

    @Autowired
    private IKuaishouLaunchGroupService kuaishouLaunchGroupService;

    @Autowired
    private IKuaishouLaunchTargetTemplateService kuaishouLaunchTargetTemplateService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private IAccountTokenService tokenService;

    /**
     * 查询投流策略
     */
    @Override
    public KuaishouLaunchCampaignAutoStrategy selectKuaishouLaunchCampaignAutoStrategyById(Long id) {
        return kuaishouLaunchCampaignAutoStrategyMapper.selectKuaishouLaunchCampaignAutoStrategyById(id);
    }

    /**
     * 查询投流策略列表
     */
    @Override
    public List<JSONObject> selectKuaishouLaunchCampaignAutoStrategyList(String campaignName, String accountName) {
        List<JSONObject> list = kuaishouLaunchCampaignAutoStrategyMapper.selectKuaishouLaunchCampaignAutoStrategyList(campaignName, accountName);
        for (JSONObject obj : list) {
            String createCountKey = DateUtils.dateTime() + obj.getLong("accountId") + obj.getLong("id");
            obj.put("groupCount", (Integer) redisUtil.get(createCountKey));
        }
        return list;
    }

    /**
     * 新增投流策略
     */
    @Override
    public ResultResponse insertKuaishouLaunchCampaignAutoStrategy(JSONObject requestJson) {
        KuaishouLaunchCampaignAutoStrategy kuaishouLaunchCampaignAutoStrategy = JSONObject.parseObject(requestJson.toJSONString(), KuaishouLaunchCampaignAutoStrategy.class);
        kuaishouLaunchCampaignAutoStrategyMapper.insertKuaishouLaunchCampaignAutoStrategy(kuaishouLaunchCampaignAutoStrategy);
        return ResultResponse.success();
    }

    /**
     * 修改投流策略
     */
    @Override
    public int updateKuaishouLaunchCampaignAutoStrategy(JSONObject requestJson) {
        KuaishouLaunchCampaignAutoStrategy kuaishouLaunchCampaignAutoStrategy = JSONObject.parseObject(requestJson.toJSONString(), KuaishouLaunchCampaignAutoStrategy.class);
        return kuaishouLaunchCampaignAutoStrategyMapper.updateKuaishouLaunchCampaignAutoStrategy(kuaishouLaunchCampaignAutoStrategy);
    }

    @Override
    public ResultResponse createByStrategy(Long id) {
        KuaishouLaunchCampaignAutoStrategy strategy = kuaishouLaunchCampaignAutoStrategyMapper.selectKuaishouLaunchCampaignAutoStrategyById(id);
        String statDate = DateUtils.getDate();
        AccountToken accountToken = tokenService.getAccountToken(strategy.getAccountId());
        String token = accountToken.getAccessToken();
        JSONObject strategyJson = (JSONObject) JSONObject.toJSON(strategy);
        //1、创建计划&获取计划ID
        Long campaignId = createCampaign(strategyJson, token);
        if (campaignId > 0) {
            strategyJson.put("campaignId", campaignId);
            //2、创建广告组
            try {
                Long unitId = createGroup(strategyJson, token);
            } catch (Exception e) {
                e.printStackTrace();
                return ResultResponse.error("广告组创建异常，" + e.getMessage());
            }
        } else {
            return ResultResponse.error("广告计划创建失败");
        }
        return ResultResponse.success();
    }

    /*创建广告计划*/
    private Long createCampaign(JSONObject strategyJson, String token) {
        JSONObject parameter = new JSONObject();
        strategyJson.put("campaignName", strategyJson.getString("campaignName") + "-" + DateUtils.dateTime());
        parameter.put("accountId", strategyJson.getLong("accountId"));
        parameter.put("campaignName", strategyJson.getString("campaignName"));
        KuaishouLaunchCampaign campaign = kuaishouLaunchCampaignService.getOne(parameter);
        if (Check.isNotNull(campaign)) {
            return campaign.getCampaignId();
        }
        return kuaishouLaunchCampaignService.insertKuaishouLaunchCampaign(strategyJson, token);
    }

    /*创建广告组*/
    private Long createGroup(JSONObject strategyJson, String token) throws Exception {
        JSONArray ocpxActionArr = strategyJson.getJSONArray("ocpxActionArr");
        JSONArray targetTemplate = strategyJson.getJSONArray("targetTemplate");
        if (Check.isNull(ocpxActionArr) || Check.isNull(targetTemplate)) {
            throw new Exception("请选择配置条件");
        }
        for (int i = 0; i < ocpxActionArr.size(); i++) {
            JSONObject ocpx = ocpxActionArr.getJSONObject(i);
            Integer type = ocpx.getInteger("type");
            strategyJson.put("ocpxActionType", type);
            String cpaBids = ocpx.getString("cpaBid");
            String[] cpaBidArr = new String[0];
            if (Check.isNotNull(cpaBids)) {
                cpaBidArr = cpaBids.split("/");
            }
            if (cpaBidArr.length > 0 && strategyJson.getInteger("speed") != 5) {
                for (int j = 0; j < cpaBidArr.length; j++) {
                    String cpaBid = cpaBidArr[j];
                    strategyJson.put("cpaBid", cpaBid);
                    for (int k = 0; k < targetTemplate.size(); k++) {
                        Long targetId = targetTemplate.getLong(k);
                        String name = getName(strategyJson, targetId, type, new BigDecimal(cpaBid));
                        strategyJson.put("newUnitName", name);
                        strategyJson = kuaishouLaunchTargetTemplateService.getTargetJson(targetId, strategyJson);
                        Long unitId = kuaishouLaunchGroupService.insertKuaishouLaunchGroup(strategyJson, token);
                        if (unitId > 0) {
                            String createCountKey = DateUtils.dateTime() + strategyJson.getLong("accountId") + strategyJson.getLong("id");
                            getTimeRedisNumberValue(createCountKey);
                            strategyJson.put("unitId", unitId);
                            kuaishouLaunchCreativeService.insertKuaishouLaunchCreative(strategyJson, token);
                            Thread.sleep(500);

                        }
                    }
                }
            } else {
                for (int k = 0; k < targetTemplate.size(); k++) {
                    Long targetId = targetTemplate.getLong(k);
                    String name = getName(strategyJson, targetId, type, null);
                    strategyJson.put("newUnitName", name);
                    strategyJson = kuaishouLaunchTargetTemplateService.getTargetJson(targetId, strategyJson);
                    Long unitId = kuaishouLaunchGroupService.insertKuaishouLaunchGroup(strategyJson, token);
                    if (unitId > 0) {
                        String createCountKey = DateUtils.dateTime() + strategyJson.getLong("accountId") + strategyJson.getLong("id");
                        getTimeRedisNumberValue(createCountKey);
                        strategyJson.put("unitId", unitId);
                        kuaishouLaunchCreativeService.insertKuaishouLaunchCreative(strategyJson, token);
                        Thread.sleep(500);
                    }
                }
            }
        }
        return 0L;

    }


    /**
     * 替换通配符（{{***}}）获取有效的计划名称/组名称
     */
    private String getName(JSONObject strategy, Long targetId, Integer ocpxActionType, BigDecimal cpaBid) {
        String unitName = strategy.getString("unitName");
        if (unitName.contains("-{{定向包名}}-") || unitName.contains("-{{人群定向名}}-") || unitName.contains("-{{人群排除名}}-")) {
            KuaishouLaunchTargetTemplate template = kuaishouLaunchTargetTemplateService.selectKuaishouLaunchTargetTemplateById(targetId);
            if (Check.isNull(template)) {
                unitName = unitName.replace("-{{定向包名}}-", "");
                unitName = unitName.replace("-{{人群定向名}}-", "");
                unitName = unitName.replace("-{{人群排除名}}-", "");
            } else {
                unitName = unitName.replace("-{{定向包名}}-", template.getTargetName());
                if (Check.isNotNull(template.getPopulationName())) {
                    unitName = unitName.replace("-{{人群定向名}}-", template.getPopulationName());
                } else {
                    unitName = unitName.replace("-{{人群定向名}}-", "");
                }
                if (Check.isNotNull(template.getExcludePopulationName())) {
                    unitName = unitName.replace("-{{人群排除名}}-", template.getExcludePopulationName());
                } else {
                    unitName = unitName.replace("-{{人群排除名}}-", "");
                }
            }
        }

        if (ocpxActionType == 72) {
            unitName = unitName.replace("-{{转化目标}}-", "粉丝关注");
        } else if (ocpxActionType == 395) {
            unitName = unitName.replace("-{{转化目标}}-", "商品购买");
        } else if (ocpxActionType == 740) {
            unitName = unitName.replace("-{{转化目标}}-", "进入直播间");
        } else if (ocpxActionType == 192) {
            unitName = unitName.replace("-{{转化目标}}-", "推广ROI");
        }

        if (Check.isNotNull(cpaBid)) {
            unitName = unitName.replace("-{{出价}}-", cpaBid.divide(new BigDecimal("1000")).toString());
        } else {
            unitName = unitName.replace("-{{出价}}-", "");
        }
        String date = DateUtils.dateTime();//yyyyMMdd
        unitName = unitName.replace("-{{日期}}-", date);
        //组序号，必填
        String redisKey = strategy.getLong("accountId") + "_" + strategy.getLong("campaignId") + date;
        Integer cnt = getTimeRedisNumberValue(redisKey);
        if (unitName.contains("-{{序号}}-")) {
            unitName = unitName.replace("-{{序号}}-", cnt + "");
        } else {
            unitName = unitName + "-" + cnt;
        }
        unitName = unitName.replace("--", "-");
        unitName = unitName.replace("--", "-");

        if (unitName.startsWith("-")) {
            unitName = unitName.substring(1, unitName.length());
        }

        if (unitName.endsWith("-")) {
            unitName = unitName.substring(0, unitName.length() - 1);
        }
        return unitName;
    }


    /**
     * 获取缓存数据
     */
    private Integer getTimeRedisNumberValue(String key) {
        Integer cnt = null;
        Integer redisCnt = (Integer) redisUtil.get(key);
        if (Check.isNull(redisCnt)) {
            cnt = 1;
            redisUtil.set(key, cnt, 100000L);
        } else {
            cnt = redisCnt + 1;
            redisUtil.set(key, cnt, 100000L);
        }
        return cnt;
    }

}