package cn.com.ctop.kuaishou.modules.batch.service.impl;

import cn.com.ctop.common.module.entity.CtopOauthToken;
import cn.com.ctop.common.module.service.ICtopOauthTokenService;
import cn.com.ctop.common.module.service.IMessageTemplate;
import cn.com.ctop.common.module.service.ISendMessageService;
import cn.com.ctop.common.module.utils.Check;
import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouGroup;
import cn.com.ctop.kuaishou.modules.batch.entity.KuaishouCampaignCopyData;
import cn.com.ctop.kuaishou.modules.batch.mapper.KuaishouCampaignCopyDataMapper;
import cn.com.ctop.kuaishou.modules.batch.service.IBatchService;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouCreativeService;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouGroupService;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouGroupTargetService;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouGroupTemplateService;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouCampaignCopyDataService;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouInterfaceService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xxl.job.core.enums.NoEn;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static java.lang.Integer.valueOf;

/**
 * 待复制广告计划数据
 *
 * @author jeecg-boot
 * @version V1.0
 * @date 2020-12-22
 */
@Service
@Slf4j
public class KuaishouCampaignCopyDataServiceImpl extends ServiceImpl<KuaishouCampaignCopyDataMapper, KuaishouCampaignCopyData> implements IKuaishouCampaignCopyDataService {
    @Autowired
    private IBatchService batchService;
    @Autowired
    private IKuaiShouGroupService kuaiShouGroupService;
    @Autowired
    private IKuaiShouGroupTargetService kuaiShouGroupTargetService;
    @Autowired
    private IKuaishouInterfaceService kuaishouInterfaceService;
    @Autowired
    private IKuaiShouCreativeService kuaiShouCreativeService;
    @Autowired
    private ICtopOauthTokenService tokenService;
    @Autowired
    private ISendMessageService sendMessageService;
    @Autowired
    private IMessageTemplate messageTemplate;
    @Autowired
    private IKuaiShouGroupTemplateService groupTemplateService;
    static ExecutorService executorService = Executors.newFixedThreadPool(15);

    /**
     * 批量复制计划
     *
     * @param
     * @return void
     * @throws
     * @author ZHAOXA
     */
    @Override
    public void batchCopyCampaign(KuaishouCampaignCopyData copyData) {
        try {
            CtopOauthToken token = tokenService.getTokenByAccountId(copyData.getAccountId());
            if (Check.isNull(token)) {
                throw new Exception("token未获取");

            }
            //执行删除被复制的计划组+创意
            delOldCampaigns(copyData.getAccountId(), copyData.getOldCampaignId());
            //获取当前最新广告计划组、创意数据并入库
            JSONObject data = getNewCampaigns(token.getAccessToken(), copyData);
            data.put("copyData", copyData);
            //根据被复制的组数据和模板、预算和排期数据调用快手创建组接口
            boolean isSuccess = createCopyUnits(token, data);
            //更新成功，修改状态并发送通知
            if (isSuccess) {
                sendNotification(copyData.getId(), copyData.getOldCampaignName(), copyData.getCreaterId(), NoEn.NO2.valueStr(), "复制成功");
            }
        } catch (Exception e) {
            log.error("复制广告计划异常", e);
            //复制过程中失败，更新状态并发送预警
            sendNotification(copyData.getId(), copyData.getOldCampaignName(), copyData.getCreaterId(), NoEn.NO3.valueStr(), e.getMessage());
        }
    }

    /**
     * 执行删除计划
     *
     * @param
     * @return void
     * @throws
     * @author ZHAOXA
     */
    private void delOldCampaigns(Long accountId, Long campaignId) throws Exception {
        try {
            log.info("删除老计划下想关联数据,accountId:{},campaignId:{}", accountId, campaignId);
            //删除组
            kuaiShouGroupService.delAllGroupByCampaignId(accountId, campaignId);
            //删除创意
            kuaiShouCreativeService.delAllCreativesByCampaignId(accountId, campaignId);
        } catch (Exception e) {
            throw new Exception("删除待复制计划失败");
        }
    }

    /**
     * 获取当前最新广告计划组、创意数据并入库
     *
     * @param
     * @return void
     * @throws
     * @author ZHAOXA
     */
    private JSONObject getNewCampaigns(String accessToken, KuaishouCampaignCopyData copyData) throws Exception {
        JSONObject data = new JSONObject();
        try {
            log.info("获取计划下最新数据,accountId:{},campaignId:{}", copyData.getAccountId(), copyData.getOldCampaignId());
            Long campaignId = copyData.getOldCampaignId();
            //根据计划ID查询快手广告组并入库
            kuaiShouGroupService.getGroupListByPage(accessToken, copyData.getAccountId(), campaignId, 1);
            //查询已入库的广告组数据
            List<KuaiShouGroup> kuaiShouGroups = kuaiShouGroupService.queryUnitInfoByCampaignId(copyData.getAccountId(), campaignId);
            if (Check.isNull(kuaiShouGroups)) {
                //获取广告组失败，更新状态并发送通知
                sendNotification(copyData.getId(), copyData.getOldCampaignName(), copyData.getCreaterId(), NoEn.NO3.valueStr(), "被复制的计划更新广告组失败");
            }
            for (KuaiShouGroup kuaiShouGroup : kuaiShouGroups) {
                kuaiShouGroup.setTarget(kuaiShouGroupTargetService.queryTargetInfoByunitId(copyData.getAccountId(), kuaiShouGroup.getUnitId()));
                //根据广告组ID查询快手广告创意并入库
            }
            data.put("groups", kuaiShouGroups);
        } catch (Exception e) {
            log.error("获取计划最新广告计划组、创意数据并入库异常", e);
            throw new Exception("获取计划最新广告计划组、创意并入库操作失败");
        }
        return data;
    }

    /**
     * 根据已有的组数据和模板、预算和排期数据调用快手创建组接口
     * detail
     *
     * @param
     * @return void
     * @throws
     * @author ZHAOXA
     */
    private boolean createCopyUnits(CtopOauthToken token, JSONObject data) throws Exception {

        int count = 0;
        String msg = "";
        JSONArray groups = data.getJSONArray("groups");
        JSONObject copyData = data.getJSONObject("copyData");
        log.info("开始创建组，accountId:{},campaign_id:{}", token.getAccountId(), copyData.getLong("newCampaignId"));
        for (int i = 0; i < groups.size(); i++) {
            try {
                JSONObject group = groups.getJSONObject(i);
                JSONObject unitJson = new JSONObject();
                unitJson.put("campaign_id", copyData.getLong("newCampaignId"));
                // 资源位置
                JSONArray scene_id = copyData.getJSONArray("sceneId");
                if (Check.isNull(scene_id)) {
                    scene_id = group.getJSONArray("sceneId");
                }
                unitJson.put("scene_id", scene_id);
                // 资源创作方式
                unitJson.put("unit_type", group.getInteger("unitType"));
                // 转化目标id
                if (!Check.isNull(group.getInteger("convertId"))) {
                    unitJson.put("convert_id", group.getInteger("convertId"));
                }
                // 优先从系统应用商店下载
                if (!Check.isNull(group.getInteger("useAppMarket"))) {
                    unitJson.put("use_app_market", group.getInteger("useAppMarket"));
                }
                // 应用商店列表
                if (!Check.isNull(group.getJSONArray("appStore"))) {
                    unitJson.put("app_store", group.getJSONArray("appStore"));
                }
                //投放开始时间
                String beginTime = copyData.getString("beginTime");
                if (Check.isNull(beginTime)) {
                    beginTime = group.getString("beginTime");
                }
                String nowDate = DateUtils.getNowDate("yyyy-MM-dd");
                boolean beginTimeBoolean = DateUtils.compare(beginTime, nowDate);
                if (beginTimeBoolean) {
                    unitJson.put("begin_time", nowDate);
                } else {
                    unitJson.put("begin_time", beginTime);
                }
                // 投放结束时间
                String endTime = copyData.getString("endTime");
                if (Check.isNull(endTime)) {
                    endTime = group.getString("endTime");
                }
                if (!Check.isNull(endTime)) {
                    unitJson.put("end_time", endTime);
                }
                // 投放时间段
                String scheduleTime = copyData.getString("scheduleTime");
                if (Check.isNull(scheduleTime)) {
                    scheduleTime = group.getString("scheduleTime");
                }
                if (!Check.isNull(scheduleTime)) {
                    unitJson.put("schedule_time", scheduleTime);
                }
                // 广告组单日预算
                Long dayBudget = copyData.getLong("dayBudget");
                if (Check.isNull(dayBudget)) {
                    dayBudget = group.getLong("dayBudget");
                }
                if (!Check.isNull(dayBudget)) {
                    unitJson.put("day_budget", dayBudget);
                }
                // url类型
                if (!Check.isNull(group.getInteger("urlType"))) {
                    unitJson.put("url_type", group.getInteger("urlType"));
                }
                // url
                if (!Check.isNull(group.getString("url"))) {
                    unitJson.put("url", group.getString("url"));
                }
                // appId
                if (!Check.isNull(group.getLong("appId"))) {
                    unitJson.put("app_id", group.getLong("appId"));
                }
                // 创意展现方式
                if (!Check.isNull(group.getInteger("showMode"))) {
                    unitJson.put("show_mode", group.getInteger("showMode"));
                }
                //投放方式
                Integer speed = copyData.getInteger("speed");
                if (Check.isNull(speed)) {
                    speed = group.getInteger("speed");
                }
                if (!Check.isNull(speed)) {
                    unitJson.put("speed", speed);
                }

                Integer sceneId = valueOf(scene_id.get(0).toString());
                Long templateId = copyData.getLong("templateId");
                if (!Check.isNull(templateId)) {
                    if (sceneId != 5) {
                        unitJson.put("template_id", templateId);
                    } else {
                        JSONObject unionJson = groupTemplateService.getUnionJson(templateId);
                        Integer code = unionJson.getInteger("code");
                        if (code == 0) {
                            JSONObject target = unionJson.getJSONObject("target");
                            unitJson.put("target", target);
                        } else {
                            continue;
                        }
                    }
                } else {
                    /*----------------用户定向-----------*/
                    JSONObject target = group.getJSONObject("target");
                    JSONObject targetJson = new JSONObject();
                    // 地域
                    if (!Check.isNull(target.getJSONArray("region"))) {
                        targetJson.put("region", target.getJSONArray("region"));
                    }
                    // 自定义年龄段
                    if (!Check.isNull(target.getInteger("ageMax")) && !Check.isNull(target.getInteger("ageMin"))) {
                        JSONObject ageJson = new JSONObject();
                        ageJson.put("min", target.getInteger("ageMin"));
                        ageJson.put("max", target.getInteger("ageMax"));
                        targetJson.put("age", ageJson);
                    }
                    // 固定年龄段
                    if (!Check.isNull(target.getJSONArray("agesRange"))) {
                        targetJson.put("ages_range", target.getJSONArray("agesRange"));
                    }
                    // 性别
                    if (!Check.isNull(target.getInteger("gender"))) {
                        targetJson.put("gender", target.getInteger("gender"));
                    }
                    //操作系统
                    if (!Check.isNull(target.getInteger("platformOs"))) {
                        targetJson.put("platform_os", target.getInteger("platformOs"));
                    }
                    //Android版本
                    if (!Check.isNull(target.getInteger("androidOsv"))) {
                        targetJson.put("android_osv", target.getInteger("androidOsv"));
                    }
                    // iOS版本
                    if (!Check.isNull(target.getInteger("iosOsv"))) {
                        targetJson.put("ios_osv", target.getInteger("iosOsv"));
                    }
                    //网络环境
                    if (!Check.isNull(target.getInteger("network"))) {
                        targetJson.put("network", target.getInteger("network"));
                    }
                    //设备品牌
                    if (!Check.isNull(target.getJSONArray("deviceBrand"))) {
                        targetJson.put("device_brand", target.getJSONArray("deviceBrand"));
                    }
                    //设备价格
                    if (!Check.isNull(target.getJSONArray("devicePrice"))) {
                        targetJson.put("device_price", target.getJSONArray("devicePrice"));
                    }
                    // APP行为-按分类
                    if (!Check.isNull(target.getJSONArray("appInterest"))) {
                        targetJson.put("app_interest", target.getJSONArray("appInterest"));
                    }
                    // APP行为-按APP名称
                    if (!Check.isNull(target.getJSONArray("appIds"))) {
                        targetJson.put("app_ids", target.getJSONArray("appIds"));
                    }
                    // 人群包定向
                    if (!Check.isNull(target.getJSONArray("population"))) {
                        targetJson.put("population", target.getJSONArray("population"));
                    }
                    // 人群包排除
                    if (!Check.isNull(target.getJSONArray("excludePopulation"))) {
                        targetJson.put("exclude_population", target.getJSONArray("excludePopulation"));
                    }
                    //三方付费人群
                    if (!Check.isNull(target.getJSONArray("thirdPlatformCode"))) {
                        targetJson.put("third_platform_code", target.getJSONArray("thirdPlatformCode"));
                    }

                    if (sceneId != 5) {
                        //过滤已转化人群纬度
                        if (!Check.isNull(target.getInteger("filterConvertedLevel"))) {
                            targetJson.put("filter_converted_level", target.getInteger("filterConvertedLevel"));
                        }
                        //商业兴趣类型
                        if (!Check.isNull(target.getInteger("businessInterestType"))) {
                            targetJson.put("business_interest_type", target.getInteger("businessInterestType"));
                        }
                        // 商业兴趣
                        if (!Check.isNull(target.getJSONArray("businessInterest"))) {
                            targetJson.put("business_interest", target.getJSONArray("businessInterest"));
                        }
                        //网红粉丝
                        if (!Check.isNull(target.getJSONArray("fansStar"))) {
                            targetJson.put("fans_star", target.getJSONArray("fansStar"));
                        }
                        //兴趣视频用户
                        if (!Check.isNull(target.getJSONArray("interestVideo"))) {
                            targetJson.put("interest_video", target.getJSONArray("interestVideo"));
                        }
                        /*----------------智能扩量----------------*/
                        JSONObject intelliExtendJson = new JSONObject();
                        // 开启智能扩量
                        if (!Check.isNull(target.getInteger("isOpen"))) {
                            intelliExtendJson.put("is_open", target.getInteger("isOpen"));
                        }
                        //不可突破年龄
                        if (!Check.isNull(target.getInteger("noAgeBreak"))) {
                            intelliExtendJson.put("no_age_break", target.getInteger("noAgeBreak"));
                        }
                        //不可突破性别
                        if (!Check.isNull(target.getInteger("noGenderBreak"))) {
                            intelliExtendJson.put("no_gender_break", target.getInteger("noGenderBreak"));
                        }
                        // 不可突破地域
                        if (!Check.isNull(target.getInteger("noAreaBreak"))) {
                            intelliExtendJson.put("no_area_break", target.getInteger("noAreaBreak"));
                        }
                        if (!Check.isNull(intelliExtendJson)) {
                            targetJson.put("intelli_extend", intelliExtendJson);
                        }
                    }
                    //-------------兴趣行为定向
                    JSONObject behaviorInterest = new JSONObject();
                    JSONObject behavior = new JSONObject();
                    JSONObject interest = new JSONObject();
                    if (!Check.isNull(target.getJSONArray("keyword"))) {
                        behavior.put("keyword", target.getJSONArray("keyword"));
                    }
                    if (!Check.isNull(target.getJSONArray("label"))) {
                        behavior.put("label", target.getJSONArray("label"));
                    }
                    if (!Check.isNull(target.getInteger("strengthType"))) {
                        behavior.put("strength_type", target.getInteger("strengthType"));
                    }
                    if (!Check.isNull(target.getInteger("timeType"))) {
                        behavior.put("time_type", target.getInteger("timeType"));
                    }
                    if (!Check.isNull(target.getJSONArray("sceneType"))) {
                        behavior.put("scene_type", target.getJSONArray("sceneType"));
                    }
                    if (!Check.isNull(target.getJSONArray("interestLabel"))) {
                        interest.put("label", target.getJSONArray("interestLabel"));
                    }
                    if (!behavior.isEmpty()) {
                        behaviorInterest.put("behavior", behavior);
                    }
                    if (!interest.isEmpty()) {
                        behaviorInterest.put("interest", interest);
                    }
                    if (!behaviorInterest.isEmpty()) {
                        targetJson.put("behavior_interest", behaviorInterest);
                    }
                    unitJson.put("target", targetJson);
                }
                // 出价
                Long bid = copyData.getLong("bid");
                if (Check.isNull(bid)) {
                    bid = group.getLong("bid");
                }
                if (!Check.isNull(bid)) {
                    unitJson.put("bid", bid);
                }
                // 出价类型
                Integer bidType = copyData.getInteger("bidType");
                if (Check.isNull(bidType)) {
                    bidType = group.getInteger("bidType");
                }
                if (!Check.isNull(bidType)) {
                    unitJson.put("bid_type", bidType);
                }
                // 深度转化出价
                Long cpaBid = copyData.getLong("cpaBid");
                if (Check.isNull(cpaBid)) {
                    cpaBid = group.getLong("cpaBid");
                }
                if (!Check.isNull(cpaBid)) {
                    unitJson.put("cpa_bid", cpaBid);
                }
                // 深度转化目标出价
                Long deepConversionBid = copyData.getLong("deepConversionBid");
                if (Check.isNull(deepConversionBid)) {
                    deepConversionBid = group.getLong("deepConversionBid");
                }
                if (!Check.isNull(deepConversionBid)) {
                    unitJson.put("deep_conversion_bid", deepConversionBid);
                }
                // 深度转化目标
                Integer deepConversionType = copyData.getInteger("deepConversionType");
                if (Check.isNull(deepConversionType)) {
                    deepConversionType = group.getInteger("deepConversionType");
                }
                if (!Check.isNull(deepConversionType)) {
                    unitJson.put("deep_conversion_type", deepConversionType);
                }
                // 优化目标
                Integer ocpxActionType = copyData.getInteger("ocpxActionType");
                if (Check.isNull(ocpxActionType)) {
                    ocpxActionType = group.getInteger("ocpxActionType");
                }
                if (!Check.isNull(ocpxActionType)) {
                    unitJson.put("ocpx_action_type", ocpxActionType);
                }

                //快手广告组名
                String unitName = group.getString("unitName");

                unitJson.put("unit_name", unitName);
                Map<String, Object> returnUnitMap = kuaishouInterfaceService.adUnitCreate(token.getAccessToken(), token.getAccountId(), unitJson, 1);
                if (!Check.isNullMap(returnUnitMap)) {
                    Integer code = (Integer) returnUnitMap.get("code");
                    if (code == 0) {
                        Long unitId = (Long) returnUnitMap.get("unitId");
                        createCopyCreatives(token, unitId, group.getLong("unitId"));
                    } else {
                        count++;
                        msg = (String) returnUnitMap.get("message");
                    }
                } else {
                    count++;
                }
            } catch (Exception e) {
                count++;
                log.error("复制过程调用快手接口异常", e);
            }
        }
        //复制广告组全部成功
        if (count == 0) {
            return true;
        } else {
            sendNotification(copyData.getLong("id"), copyData.getString("oldCampaignName"), copyData.getString("createrId"), NoEn.NO3.valueStr(), msg);
        }
        return false;
    }

    /**
     * 根据已有创意数据，匹配新计划、组数据调用快手创建创意接口
     *
     * @param
     * @return void
     * @throws
     * @author ZHAOXA
     */
    private void createCopyCreatives(CtopOauthToken token, Long unitId, Long copyUnitId) {
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                try {
                    log.info("开始多线程执行创建创意,accountId:{},新组：{}，老组：{}", token.getAccountId(), unitId, copyUnitId);
                    kuaiShouGroupService.getCreativeByUnit(token.getAccessToken(), token.getAccountId(), copyUnitId);
                    Thread.sleep(200L);
                    batchService.copyCreative(token.getAccountId(), unitId, copyUnitId, null);
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        });


    }

    /**
     * 发送消息通知
     *
     * @param
     * @return void
     * @throws
     * @author ZHAOXA
     */
    private void sendNotification(Long id, String name, String userId, String state, String StateDetail) {
        KuaishouCampaignCopyData copyData = new KuaishouCampaignCopyData();
        copyData.setId(id);
        copyData.setState(state);
        copyData.setStateDetail(StateDetail);
        this.updateById(copyData);
        String msg = messageTemplate.getCopyCampaignMessage(name, state);
        sendMessageService.sendMessage(userId, msg);
    }
}
