package org.jeecg.modules.bytedance.advertise.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.bytedance.advertise.dockapi.MarketingService;
import org.jeecg.modules.bytedance.advertise.entity.*;
import org.jeecg.modules.bytedance.advertise.enums.BytedanceCreativeMatTypeEnum;
import org.jeecg.modules.bytedance.advertise.mapper.AiBytedanceAdvertiserStrategyMapper;
import org.jeecg.modules.bytedance.advertise.mapper.BytedanceAreaInfoMapper;
import org.jeecg.modules.bytedance.advertise.service.*;
import org.jeecg.modules.bytedance.advertise.vo.AdConvertQueryVo;
import org.jeecg.modules.bytedance.advertise.vo.AdGroupSearchVo;
import org.jeecg.modules.bytedance.advertise.vo.IndustryVo;
import org.jeecg.modules.bytedance.advertise.vo.PlanSearchVo;
import org.jeecg.modules.bytedance.common.constant.BytedanceConstant;
import org.jeecg.modules.bytedance.common.entity.CtopOauthToken;
import org.jeecg.modules.bytedance.common.entity.MaterialImageInfo;
import org.jeecg.modules.bytedance.common.entity.MaterialInfo;
import org.jeecg.modules.bytedance.common.entity.UserAllocation;
import org.jeecg.modules.bytedance.common.service.*;
import org.jeecg.modules.bytedance.common.utils.Check;
import org.jeecg.modules.bytedance.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 头条智能投放账户配置信息表
 * @author jeecg-boot
 * 2021-04-20
 * @version V1.0
 */
@Service
@Slf4j
public class AiBytedanceAdvertiserStrategyServiceImpl extends ServiceImpl<AiBytedanceAdvertiserStrategyMapper, AiBytedanceAdvertiserStrategy> implements IAiBytedanceAdvertiserStrategyService {
    @Autowired
    private IBytedanceVideoSlogenInfoService slogenInfoService;
    @Autowired
    private IFileInfoService fileInfoService;
    @Resource
    private AiBytedanceAdvertiserStrategyMapper aiBytedanceAdvertiserStrategyMapper;
    @Autowired
    private ICtopOauthTokenService tokenService;
    @Autowired
    private IMaterialImageInfoService materialImageInfoService;
    @Autowired
    private IUserAllocationService userAllocationService;
    @Autowired
    private IBytedanceImageInfoService bytedanceImageInfoService;
    @Autowired
    private IMaterialInfoService materialInfoService;
    @Autowired
    private IByteDanceCampaignService campaignService;
    @Autowired
    private IAiBytedanceAdDplinkInfoService adDplinkInfoService;
    @Autowired
    private IByteDanceVideoInfoService videoInfoService;
    @Autowired
    private MarketingService marketingService;

    @Override
    public Long createCreative(AiBytedanceAdvertiserStrategy strategy, Integer createType, Long videoCnt, String openUrl) {
        CtopOauthToken token = tokenService.getOauthTokenByAccountId(strategy.getAccountId()+"");
        if (null == token) {
            log.info("token获取失败=>accountId:{}", strategy.getAccountId());
            return videoCnt;
        }

        UserAllocation userAllocation = userAllocationService.getByAccountId(strategy.getAccountId());
        if(null == userAllocation||userAllocation.getAccountStatus()!=0){
            log.info("此账户不存在或者已经被关闭=>accountId:{}", token.getAccountId());
            return videoCnt;
        }
        //查询相应的素材信息
        Long timeStart = BytedanceCreativeMatTypeEnum.getStartTimeByType(createType.toString());
        Long timeEnd = BytedanceCreativeMatTypeEnum.getEndTimeByType(createType.toString());
        Long now = System.currentTimeMillis();
        String startTime = DateUtils.formatDateTime(now + timeStart * 60 * 1000L);
        String endTime = DateUtils.formatDateTime(now + timeEnd * 60 * 1000L);
        List<ByteDanceVideoInfo> videoInfos = getVideoInfoByCreateType(userAllocation.getProjectId(),strategy,startTime,endTime,createType,videoCnt);
        if(null == videoInfos||videoInfos.isEmpty()){
            log.info("获取视频素材为空=>accountId:{}", token.getAccountId());
            return videoCnt;
        }

        for (ByteDanceVideoInfo video:videoInfos) {
            //1：过滤掉所有不存在于视频库的数据
            MaterialInfo materialInfo = materialInfoService.getParams(video.getSignature(),1);
            if(null == materialInfo){
                continue;
            }
            //过滤掉所有未绑定文案的数据
            List<BytedanceVideoSlogenInfo>slogenInfos = slogenInfoService.listByParams(video.getSignature(),1);
            if(null == slogenInfos||slogenInfos.isEmpty()){
                continue;
            }
            // 2:创建计划
            Long dpIndex ;
            AiBytedanceAdDplinkInfo adDplinkInfo = adDplinkInfoService.getlatestDpLinkInfo(strategy.getId(),strategy.getAccountId(),1);
            if(null == adDplinkInfo){
                adDplinkInfo = new AiBytedanceAdDplinkInfo();
                if("FIX".equalsIgnoreCase(strategy.getAdBidCreateType())){
                    adDplinkInfo.setAdBid(strategy.getAdCpaBid());
                }else{
                    adDplinkInfo.setAdBid(strategy.getAdMinBid());
                }
                adDplinkInfo.setDpLinkIndex(strategy.getDpLinkStartIndex());
            }else{
                adDplinkInfo.setId(null);
                adDplinkInfo.setDpLinkIndex(adDplinkInfo.getDpLinkIndex()+1);
            }
            dpIndex = adDplinkInfo.getDpLinkIndex();
            if(dpIndex>strategy.getDpLinkEndIndex()){
                log.info("此账户策略创建结束=>账户id:{};策略id:{}", token.getAccountId(),strategy.getId());
                return 0L;
            }
            String campaignName = getCampaignName(strategy,dpIndex);
            Long campaignId = getCampaignId(strategy,campaignName,token);
            if(null == campaignId){
                return videoCnt;
            }
            strategy.setAdOpenUrl(openUrl.replace("{{dp链接下标}}",dpIndex.toString()));
            String dplinkCode = StringUtils.getParamFromUrl(strategy.getAdOpenUrl(),"bc_fl_src");
            String adName = getAdName(strategy,dplinkCode,video);
            //计算本次出价
            BigDecimal currentCpaBid = StringUtils.getRandomAdCpaBid(strategy.getAdBidCreateType(),strategy.getAdMaxBid(),strategy.getAdMinBid(),strategy.getAdStepBid(),adDplinkInfo.getAdBid());
            adDplinkInfo.setAdBid(currentCpaBid);
            JSONObject adParams = getAdParams(strategy,adName,campaignId,currentCpaBid);
            Long adId = createAdInfo(token,strategy,adParams);
            if(null == adId){
                continue;
            }
            adDplinkInfo.setAdId(adId);
            adDplinkInfo.setAccountId(strategy.getAccountId());
            adDplinkInfo.setStatus(1);
            adDplinkInfo.setStrategyId(strategy.getId());
            adDplinkInfoService.save(adDplinkInfo);
            //3:创建创意
            JSONObject creativeParams = getCreativeParams(strategy,adId,video,token);
            log.info("创意创建参数:{}",creativeParams);
            JSONObject creativeObject =  marketingService.creativeCreate(token,adId,creativeParams);
            if(null!=creativeObject.getInteger("code")&&creativeObject.getInteger("code")!=0){
                String message = creativeObject.getString("message");
                Integer code = creativeObject.getInteger("code");
                //创建创意失败
                log.info("创意创建失败:code==>{};message==>{}",code,message);
                continue;
            }
            videoCnt --;
            if(videoCnt<=0){
                return 0L;
            }
        }
        return videoCnt;
    }
    private JSONObject getCreativeParams(AiBytedanceAdvertiserStrategy strategy, Long adId,ByteDanceVideoInfo videoInfo,CtopOauthToken token) {
        JSONObject params = new JSONObject();
        params.put("advertiser_id",strategy.getAccountId());
        params.put("ad_id",adId);
        String inventoryType = strategy.getCreativeInventoryType();
        if(null!=inventoryType&&!"".equals(inventoryType)){
            String[] inventoryTypeString = inventoryType.split(",");
            if(inventoryTypeString.length>0){
              params.put("inventory_type",inventoryTypeString);
            }
        }
        Integer smartInventory = strategy.getCreativeSmartInventory();
        if(null!=smartInventory&&smartInventory!=0){
            params.put("smart_inventory",smartInventory);
        }

        String sceneInventory = strategy.getCreativeSceneInventory();
        if(!Check.isNull(sceneInventory)){
            params.put("scene_inventory",sceneInventory);
        }
        //程序化创意 非dpa
        params.put("creative_material_mode","STATIC_ASSEMBLE");
        //是否自动生成视频素材
        Integer isPresentedVideo = strategy.getCreativeIsPresentedVideo();
        if(null!=isPresentedVideo&&isPresentedVideo!=0){
            params.put("is_presented_video",isPresentedVideo);
        }
        //是否开启衍生计划
        Integer generateDerivedAd = strategy.getCreativeGenerateDerivedAd();
        if(null!=generateDerivedAd&&generateDerivedAd!=0){
            params.put("generate_derived_ad",generateDerivedAd);
        }
        //视频素材
        JSONArray imageArray = new JSONArray();
        JSONObject imageObject = new JSONObject();
        //视频类型
        if(videoInfo.getType() == 1){
            //竖版视频
            imageObject.put("image_mode","CREATIVE_IMAGE_MODE_VIDEO_VERTICAL");
        }
        if(videoInfo.getType() == 2){
            //横版视频
            imageObject.put("image_mode","CREATIVE_IMAGE_MODE_VIDEO");
        }
        imageObject.put("video_id",videoInfo.getVid());
        //获取视频封面id
        String imageId = getSuggestImageId(token,videoInfo.getVid());
        if(!Check.isNull(imageId)){
            imageObject.put("image_id",imageId);
        }
        imageArray.add(imageObject);
        params.put("image_list",imageArray);
        JSONArray titleArray = new JSONArray();
        List<BytedanceVideoSlogenInfo>slogenInfos = slogenInfoService.listByParams(videoInfo.getSignature(),1);
        if(!Check.isNull(slogenInfos)){
            slogenInfos.forEach(slogenInfo->{
                JSONObject titleObject = new JSONObject();
                titleObject.put("title",slogenInfo.getSlogan());
                titleArray.add(titleObject);
            });
        }
        if(!Check.isNull(titleArray)){
            params.put("title_list",titleArray);
        }
        //广告来源
        String source = strategy.getCreativeSource();
        if(!Check.isNull(source)){
            params.put("source",source);
        }
        //推广抖音号
        String iesCoreUserId = strategy.getCreativeIesCoreUserId();
        if(!Check.isNull(iesCoreUserId)){
            params.put("ies_core_user_id",iesCoreUserId);
        }
        //主页作品列表隐藏广告内容
        Integer isFeedAndFavSee = strategy.getCreativeIsFeedAndFavSee();
        if(null!=isFeedAndFavSee&&isFeedAndFavSee!=0){
            params.put("is_feed_and_fav_see",isFeedAndFavSee);
        }
        //是否开启自动生成素材
        Integer creativeAutoGenerateSwitch = strategy.getCreativeAutoGenerateSwitch();
        if(null!=creativeAutoGenerateSwitch&&creativeAutoGenerateSwitch!=1){
            params.put("creative_auto_generate_switch",creativeAutoGenerateSwitch);
        }
        String appName = strategy.getCreativeAppName();
        if(!Check.isNull(appName)){
            params.put("app_name",appName);
        }

        String subTitle = strategy.getCreativeSubTitle();
        if(!Check.isNull(subTitle)){
            params.put("sub_title",subTitle);
        }

        String webUrl = strategy.getCreativeWebUrl();
        if(!Check.isNull(webUrl)){
            params.put("web_url",webUrl);
        }

        String actionText = strategy.getCreativeActionText();
        if(!Check.isNull(actionText)){
            params.put("action_text",actionText);
        }

        String playableUrl = strategy.getCreativePlayableUrl();
        if(!Check.isNull(playableUrl)){
            params.put("playable_url",playableUrl);
        }

        Integer isCommentDisable = strategy.getCreativeIsCommentDisable();
        if(!Check.isNull(isCommentDisable)&&isCommentDisable!=0){
            params.put("is_comment_disable",appName);
        }
        String creativeDisplayMode = strategy.getCreativeDisplayMode();
        if(!Check.isNull(creativeDisplayMode)){
            params.put("creative_display_mode",creativeDisplayMode);
        }
//        允许客户端下载视频功能
//        Integer adDownloadStatus = strategy.getCreativeAdDownloadStatus();
//        if(!Check.isNull(adDownloadStatus)&&adDownloadStatus!=0){
//            params.put("ad_download_status",adDownloadStatus);
//        }
        //商品推广卡片
        String imageCode = strategy.getCreativeProductImageCode();
        if(!Check.isNull(imageCode)){
            //1:根据imageCode获取图片id
            JSONObject promotionCard = new JSONObject();
            String iconImageId = getBytedanceImageIdByCode(imageCode,token);
            if(!Check.isNull(iconImageId)){
                promotionCard.put("product_image_id",iconImageId);
            }
            String productSellingPoints = strategy.getCreativeProductSellingPoints();
            if(!Check.isNull(productSellingPoints)){
                String[] pointString = productSellingPoints.split(",");
                if(pointString.length>0){
                    promotionCard.put("product_selling_points",pointString);
                }
            }
            String productDescription = strategy.getCreativeProductDescription();
            if(!Check.isNull(productDescription)){
                promotionCard.put("product_description",productDescription);
            }
            Boolean enableStorePack = strategy.getCreativeEnablePersonalAction();
            if(null!=enableStorePack){
                promotionCard.put("enable_store_pack",enableStorePack);
            }
            String callToAction = strategy.getCreativeCallToAction();
            if(!Check.isNull(callToAction)){
                promotionCard.put("call_to_action",callToAction);
            }
            Boolean enablePersonalAction = strategy.getCreativeEnablePersonalAction();
            if(null!=enablePersonalAction){
                promotionCard.put("enable_personal_action",enablePersonalAction);
            }
            params.put("promotion_card",promotionCard);
        }
        //行业类别
        String thirdIndustryId = strategy.getCreativeThirdIndustryId();
        if(!Check.isNull(thirdIndustryId)){
            params.put("third_industry_id",thirdIndustryId);
        }
        //关键词 添加随机关键词逻辑
        String adKeywords = strategy.getCreativeAdKeywords();
        if(!Check.isNull(adKeywords)){
            String [] keywords = adKeywords.split(",");
            if(keywords.length>0){
                if(keywords.length<=20){
                    params.put("ad_keywords",keywords);
                }else {
                    List<String>keywordList = Arrays.asList(keywords);
                    Collections.shuffle(keywordList);
                    List<String> getKeyWords = keywordList.subList(0,20);
                    params.put("ad_keywords",getKeyWords);
                }
            }
        }
        String trackUrl = strategy.getCreativeTrackUrl();
        if(!Check.isNull(trackUrl)){
            params.put("track_url",trackUrl);
        }
        String actionTrackUrl = strategy.getCreativeActionTrackUrl();
        if(!Check.isNull(actionTrackUrl)){
            params.put("action_track_url",actionTrackUrl);
        }
        String videoPlayEffectiveTrackUrl = strategy.getCreativeVideoPlayEffectiveTrackUrl();
        if(!Check.isNull(videoPlayEffectiveTrackUrl)){
            params.put("video_play_effective_track_url",videoPlayEffectiveTrackUrl);
        }
//        String videoPlayDoneTrackUrl = strategy.getCreativeVideoPlayDoneTrackUrl();
//        if(!Check.isNull(videoPlayDoneTrackUrl)){
//            params.put("video_play_done_track_url",videoPlayDoneTrackUrl);
//        }
        String videoPlayTrackUrl = strategy.getCreativeVideoPlayTrackUrl();
        if(!Check.isNull(videoPlayTrackUrl)){
            params.put("video_play_track_url",videoPlayTrackUrl);
        }
        return params;

    }

    private String getBytedanceImageIdByCode(String imageCode, CtopOauthToken token) {
        //1：根据code获取图片信息
        BytedanceImageInfo bytedanceImageInfo = bytedanceImageInfoService.getByParams(imageCode);
        if(null!=bytedanceImageInfo){
            return bytedanceImageInfo.getId();
        }
        //2:根据code查询图片素材信息
        MaterialImageInfo imageInfo = materialImageInfoService.getByCode(imageCode);
        if(null ==  imageInfo){
            return null;
        }
        Map<String, Object> result = fileInfoService.uploadImageToBytedance(token.getAccountId().toString(),imageInfo.getUrl());
        Integer code = (Integer) result.get("code");
        if(null == code||code!=0){
            return null;
        }
        BytedanceImageInfo info  = (BytedanceImageInfo)result.get("data");
        if(null != info&&null!=info.getId()){
            return info.getId();
        }
        return null;
        //图片上传头条巨量后台
    }

    private String getSuggestImageId(CtopOauthToken token, String vid) {
        return fileInfoService.getSuggestImageId(token,vid);
    }

    private Long createAdInfo(CtopOauthToken token, AiBytedanceAdvertiserStrategy strategy, JSONObject adParams) {
        Result result = marketingService.createAdvertiserPlan(token,adParams,strategy);
        if(result.getCode()!=0){
            //TODO 计划创建异常 后续需要加日志
            return null;
        }
        return (Long)result.getResult();
    }

    private JSONObject getAdParams(AiBytedanceAdvertiserStrategy strategy, String adName, Long campaignId,BigDecimal currentCpaBid) {
        JSONObject params = new JSONObject();
        //公共参数
        params.put("advertiser_id",strategy.getAccountId());
        params.put("campaign_id",campaignId);
        params.put("name",adName);
        //竞价策略 默认优先跑量
        params.put("flow_control_mode","FLOW_CONTROL_MODE_FAST");
        //投放范围
        params.put("delivery_range",strategy.getAdDeliveryRange());
        if(!Check.isNull(strategy.getAdUnionVideoType())){
            params.put("union_video_type",strategy.getAdUnionVideoType());
        }
        //投放目标
        params.put("download_type",strategy.getAdDownloadType());
        if(!Check.isNull(strategy.getAdDownloadUrl())){
            params.put("download_url",strategy.getAdDownloadUrl());
        }
        if(!Check.isNull(strategy.getAdQuickAppUrl())){
            params.put("quick_app_url",strategy.getAdQuickAppUrl());
        }
        if(!Check.isNull(strategy.getAdExternalUrl())){
            params.put("external_url",strategy.getAdExternalUrl());
        }
        if(!Check.isNull(strategy.getAdAppType())){
            params.put("app_type",strategy.getAdAppType());
        }
        if(!Check.isNull(strategy.getAdPackage())){
            params.put("package",strategy.getAdPackage());
        }
        if(!Check.isNull(strategy.getAdDownloadMode())){
            params.put("download_mode",strategy.getAdDownloadMode());
        }
        if(!Check.isNull(strategy.getAdConvertId())){
            params.put("convert_id",strategy.getAdConvertId());
        }
        if(!Check.isNull(strategy.getAdOpenUrl())){
            params.put("open_url",strategy.getAdOpenUrl());
        }
        if(!Check.isNull(strategy.getAdAdvancedCreativeType())){
            params.put("advanced_creative_type",strategy.getAdAdvancedCreativeType());
        }
        if(!Check.isNull(strategy.getAdGamePackageDesc())){
            params.put("game_package_desc",strategy.getAdGamePackageDesc());
        }
        if(!Check.isNull(strategy.getAdGamePackageBatchId())){
            params.put("game_package_batch_id",strategy.getAdGamePackageBatchId());
        }
        if(!Check.isNull(strategy.getAdGamePackageThumbnailId())){
            JSONArray ids = JSON.parseArray(strategy.getAdGamePackageThumbnailId());
            if(null != ids&&!ids.isEmpty()){
                params.put("game_package_thumbnail_ids",ids);
            }
        }
        //用户定向
        if(!Check.isNull(strategy.getAdAudiencePackageId())){
            params.put("audience_package_id",strategy.getAdAudiencePackageId());
        }
        if(!Check.isNull(strategy.getAdDistrict())){
            params.put("district",strategy.getAdDistrict());
        }
        if(!Check.isNull(strategy.getAdCity())){
            String[] city = strategy.getAdCity().split(",");
            if(city.length>0){
                params.put("city",city);
            }
        }
        if(!Check.isNull(strategy.getAdLocationType())){
            params.put("location_type",strategy.getAdLocationType());
        }
        if(!Check.isNull(strategy.getAdGender())){
            params.put("gender",strategy.getAdGender());
        }
        if(!Check.isNull(strategy.getAdAge())){
            String[] age = strategy.getAdAge().split(",");
            if(age.length>0){
                JSONArray ageArray = new JSONArray();
                for(int i=0;i<age.length;i++){
                    if(null!=age[i]&&!"NONE".equals(age[i])){
                        ageArray.add(age[i]);
                    }
                }
                if(!ageArray.isEmpty()){
                    params.put("age",ageArray);
                }
            }
        }
        if(!Check.isNull(strategy.getAdRetargetingTagsInclude())){
            String[] retargetingTagsInclude = strategy.getAdRetargetingTagsInclude().split(",");
            if(retargetingTagsInclude.length>0){
                JSONArray retargetingTagsIncludeArray = new JSONArray();
                for(int i=0;i<retargetingTagsInclude.length;i++){
                    if(null!=retargetingTagsInclude[i]&&!"NONE".equals(retargetingTagsInclude[i])){
                        retargetingTagsIncludeArray.add(Long.parseLong(retargetingTagsInclude[i]));
                    }
                }
                if(!retargetingTagsIncludeArray.isEmpty()){
                    params.put("retargeting_tags_include",retargetingTagsIncludeArray);
                }
            }
        }
        if(!Check.isNull(strategy.getAdRetargetingTagsExclude())){
            String[] getAdRetargetingTagsExclude = strategy.getAdRetargetingTagsExclude().split(",");
            if(getAdRetargetingTagsExclude.length>0){
                JSONArray getAdRetargetingTagsExcludeArray = new JSONArray();
                for(int i=0;i<getAdRetargetingTagsExclude.length;i++){
                    if(null!=getAdRetargetingTagsExclude[i]&&!"NONE".equals(getAdRetargetingTagsExclude[i])){
                        getAdRetargetingTagsExcludeArray.add(getAdRetargetingTagsExclude[i]);
                    }
                }
                if(!getAdRetargetingTagsExcludeArray.isEmpty()){
                    params.put("retargeting_tags_exclude",getAdRetargetingTagsExcludeArray);
                }
            }
        }
        if(!Check.isNull(strategy.getAdInterestActionMode())){
            params.put("interest_action_mode",strategy.getAdInterestActionMode());
        }
        if(!Check.isNull(strategy.getAdActionScene())){
            String[] actionScene = strategy.getAdActionScene().split(",");
            if(actionScene.length>0){
                JSONArray actionSceneArray = new JSONArray();
                for(int i=0;i<actionScene.length;i++){
                    actionSceneArray.add(actionScene[i]);
                }
                params.put("action_scene",actionSceneArray);
            }
        }
        if(!Check.isNull(strategy.getAdActionDays())){
            params.put("action_days",strategy.getAdActionDays());
        }
        if(!Check.isNull(strategy.getAdActionCategories())){
            String[] actionCategories = strategy.getAdActionCategories().split(",");
            if(actionCategories.length>0){
                JSONArray actionCategoriesArray = new JSONArray();
                for(int i=0;i<actionCategories.length;i++){
                    actionCategoriesArray.add(actionCategories[i]);
                }
                params.put("action_categories",actionCategoriesArray);
            }
        }
        if(!Check.isNull(strategy.getAdActionWords())){
            String[] actionWords = strategy.getAdActionWords().split(",");
            if(actionWords.length>0){
                JSONArray actionWordsArray = new JSONArray();
                for(int i=0;i<actionWords.length;i++){
                    actionWordsArray.add(actionWords[i]);
                }
                params.put("action_words",actionWordsArray);
            }
        }
        if(!Check.isNull(strategy.getAdInterestCategories())){
            String[] interestCategories = strategy.getAdInterestCategories().split(",");
            if(interestCategories.length>0){
                JSONArray interestCategoriesArray = new JSONArray();
                for(int i=0;i<interestCategories.length;i++){
                    interestCategoriesArray.add(interestCategories[i]);
                }
                params.put("interest_categories",interestCategoriesArray);
            }
        }
        if(!Check.isNull(strategy.getAdInterestWords())){
            String[] interestWords = strategy.getAdInterestWords().split(",");
            if(interestWords.length>0){
                params.put("interest_words",interestWords);
            }
        }
        if(!Check.isNull(strategy.getAdAwemeFanBehaviors())){
            String[] awemeFanBehaviors = strategy.getAdAwemeFanBehaviors().split(",");
            if(awemeFanBehaviors.length>0){
                params.put("aweme_fan_behaviors",awemeFanBehaviors);
            }
        }
        if(!Check.isNull(strategy.getAdAwemeFanCategories())){
            String[] awemeFanCategories = strategy.getAdAwemeFanCategories().split(",");
            if(awemeFanCategories.length>0){
                params.put("aweme_fan_categories",awemeFanCategories);
            }
        }
        if(!Check.isNull(strategy.getAdAwemeFanAccounts())){
            String[] awemeFanAccount = strategy.getAdAwemeFanAccounts().split(",");
            if(awemeFanAccount.length>0){
                params.put("aweme_fan_accounts",awemeFanAccount);
            }
        }
        if(!Check.isNull(strategy.getAdAwemeFansNumbers())){
            String[] awemeFansNumbers = strategy.getAdAwemeFansNumbers().split(",");
            if(awemeFansNumbers.length>0){
                params.put("aweme_fans_numbers",awemeFansNumbers);
            }
        }
        if(!Check.isNull(strategy.getAdFilterAwemeAbnormalActive())){
            params.put("filter_aweme_abnormal_active",strategy.getAdFilterAwemeAbnormalActive());
        }
        if(!Check.isNull(strategy.getAdFilterAwemeFansCount())){
            params.put("filter_aweme_fans_count",strategy.getAdFilterAwemeFansCount());
        }
        if(!Check.isNull(strategy.getAdFilterOwnAwemeFans())){
            params.put("filter_own_aweme_fans",strategy.getAdFilterOwnAwemeFans());
        }
        if(!Check.isNull(strategy.getAdSuperiorPopularityType())){
            params.put("superior_popularity_type",strategy.getAdSuperiorPopularityType());
        }
        if(!Check.isNull(strategy.getAdFlowPackage())){
            String[] flowPackage = strategy.getAdFlowPackage().split(",");
            if(flowPackage.length>0){
                params.put("flow_package",flowPackage);
            }
        }
        if(!Check.isNull(strategy.getAdExcludeFlowPackage())){
            String[] excludeFlowPackage = strategy.getAdExcludeFlowPackage().split(",");
            if(excludeFlowPackage.length>0){
                params.put("exclude_flow_package",excludeFlowPackage);
            }
        }
        if(!Check.isNull(strategy.getAdPlatform())){
            String[] platform = strategy.getAdPlatform().split(",");
            if(platform.length>0){
                params.put("platform",platform);
            }
        }

        if(!Check.isNull(strategy.getAdAndroidOsv())){
            params.put("android_osv",strategy.getAdAndroidOsv());
        }

        if(!Check.isNull(strategy.getAdAdIosOsv())){
            params.put("ios_osv",strategy.getAdAdIosOsv());
        }
        if(!Check.isNull(strategy.getAdAc())){
            String[] ac = strategy.getAdAc().split(",");
            if(ac.length>0){
                JSONArray acArray = new JSONArray();
                for(int i=0;i<ac.length;i++){
                    if(null!=ac[i]&&!"NONE".equals(ac[i])){
                        acArray.add(ac[i]);
                    }
                }
                if(!acArray.isEmpty()){
                    params.put("ac",acArray);
                }
            }
        }
        if(!Check.isNull(strategy.getAdCarrier())){
            String[] carrier = strategy.getAdCarrier().split(",");
            if(carrier.length>0){
                JSONArray carrierArray = new JSONArray();
                for(int i=0;i<carrier.length;i++){
                    if(null!=carrier[i]&&!"NONE".equals(carrier[i])) {
                        carrierArray.add(carrier[i]);
                    }
                }
                if(!carrierArray.isEmpty()){
                    params.put("carrier",carrierArray);
                }
            }
        }
        if(!Check.isNull(strategy.getAdDeviceType())){
            String[] deviceType = strategy.getAdDeviceType().split(",");
            if(deviceType.length>0){
                JSONArray deviceTypeArray = new JSONArray();
                for(int i=0;i<deviceType.length;i++){
                    deviceTypeArray.add(deviceType[i]);
                }
                params.put("device_type",deviceTypeArray);
            }
        }

        if(!Check.isNull(strategy.getAdHideIfExists())){
            params.put("hide_if_exists",strategy.getAdHideIfExists());
        }
        if(!Check.isNull(strategy.getAdConvertedTimeDuration())){
            params.put("converted_time_duration",strategy.getAdConvertedTimeDuration());
        }
        if(!Check.isNull(strategy.getAdHideIfConverted())){
            params.put("hide_if_converted",strategy.getAdHideIfConverted());
        }

        if(!Check.isNull(strategy.getAdActivateType())){
            String[] activateType = strategy.getAdActivateType().split(",");
            if(activateType.length>0){
                JSONArray activateTypeArray = new JSONArray();
                for(int i=0;i<activateType.length;i++){
                    activateTypeArray.add(activateType[i]);
                }
                params.put("activate_type",activateTypeArray);
            }
        }
        if(!Check.isNull(strategy.getAdArticleCategory())){
            String[] articleCategory = strategy.getAdArticleCategory().split(",");
            if(articleCategory.length>0){
                JSONArray articleCategoryArray = new JSONArray();
                for(int i=0;i<articleCategory.length;i++){
                    articleCategoryArray.add(articleCategory[i]);
                }
                params.put("article_category",articleCategoryArray);
            }
        }
        if(!Check.isNull(strategy.getAdDeviceBrand())){
            String[] deviceBrand = strategy.getAdDeviceBrand().split(",");
            if(deviceBrand.length>0){
                JSONArray deviceBrandArray = new JSONArray();
                for(int i=0;i<deviceBrand.length;i++){
                    deviceBrandArray.add(deviceBrand[i]);
                }
                params.put("device_brand",deviceBrandArray);
            }
        }
        if(!Check.isNull(strategy.getAdLaunchPrice())){
            String[] launchPrice = strategy.getAdLaunchPrice().split(",");
            if(launchPrice.length>0){
                JSONArray launchPriceArray = new JSONArray();
                for(int i=0;i<launchPrice.length;i++){
                    launchPriceArray.add(launchPrice[i]);
                }
                params.put("launch_price",launchPriceArray);
            }
        }
        if(!Check.isNull(strategy.getAdAutoExtendEnabled())){
            params.put("auto_extend_enabled",strategy.getAdAutoExtendEnabled());
        }
        if(!Check.isNull(strategy.getAdAutoExtendTargets())){
            String[] autoExtendTargets = strategy.getAdAutoExtendTargets().split(",");
            if(autoExtendTargets.length>0){
                JSONArray autoExtendTargetsArray = new JSONArray();
                for(int i=0;i<autoExtendTargets.length;i++){
                    autoExtendTargetsArray.add(autoExtendTargets[i]);
                }
                params.put("auto_extend_targets",autoExtendTargetsArray);
            }
        }
        //预算与出价
        if(!Check.isNull(strategy.getAdSmartBidType())){
            params.put("smart_bid_type",strategy.getAdSmartBidType());
        }
        if(!Check.isNull(strategy.getAdAdjustCpa())){
            params.put("adjust_cpa",strategy.getAdAdjustCpa());
        }
        if(!Check.isNull(strategy.getAdFlowControlMode())){
            params.put("flow_control_mode",strategy.getAdFlowControlMode());
        }
        if(!Check.isNull(strategy.getAdBudgetMode())){
            params.put("budget_mode",strategy.getAdBudgetMode());
        }
        if(!Check.isNull(strategy.getAdBudget())){
            params.put("budget",strategy.getAdBudget());
        }
        if(!Check.isNull(strategy.getAdScheduleType())){
            params.put("schedule_type",strategy.getAdScheduleType());
        }
        if(!Check.isNull(strategy.getAdStartTime())){
            params.put("start_time",strategy.getAdStartTime());
        }
        if(!Check.isNull(strategy.getAdAdjustCpa())){
            params.put("end_time",strategy.getAdEndTime());
        }
        if(!Check.isNull(strategy.getAdScheduleTime())){
            params.put("schedule_time",strategy.getAdScheduleTime());
        }
        if(!Check.isNull(strategy.getAdPricing())){
            params.put("pricing",strategy.getAdPricing());
        }
        if(!Check.isNull(strategy.getAdBid())){
            params.put("bid",strategy.getAdBid());
        }
        params.put("cpa_bid",currentCpaBid);
        if(!Check.isNull(strategy.getAdDeepBidType())){
            params.put("deep_bid_type",strategy.getAdDeepBidType());
        }
        if(!Check.isNull(strategy.getAdDeepCpabid())){
            params.put("deep_cpabid",strategy.getAdDeepCpabid());
        }
        if(!Check.isNull(strategy.getAdLubanRoiGoal())){
            params.put("luban_roi_goal",strategy.getAdLubanRoiGoal());
        }
        if(!Check.isNull(strategy.getAdRoiGoal())){
            params.put("roi_goal",strategy.getAdRoiGoal());
        }
        return params;
    }

    private String getAdName(AiBytedanceAdvertiserStrategy strategy, String dplinkCode, ByteDanceVideoInfo videoInfo) {
        String adName = strategy.getAdName();
        if(null == adName|| "".equals(adName.trim())){
            return null;
        }
        if(adName.contains("{{日期}}")){
            String date = DateUtils.formatDate(new Date(),"yyyyMMdd");
            adName = adName.replace("{{日期}}",date);
        }
        if(adName.contains("{{dp链接标识}}")){
            adName = adName.replace("{{dp链接标识}}",dplinkCode);
        }
        if(adName.contains("{{出价方式}}")){
            String pricing = strategy.getAdPricing().replace("PRICING_","");
            adName = adName.replace("{{出价方式}}",pricing);
        }
        if(adName.contains("{{素材名称}}")){
            MaterialInfo info = materialInfoService.getParams(videoInfo.getSignature(),null);
            if(null!=info&&null!=info.getMaterialName()){
                adName = adName.replace("{{素材名称}}",info.getMaterialName());
            }
        }
        adName = adName.replace("--","-");
        if(adName.startsWith("-")){
            adName = adName.substring(1);
        }
        if(adName.endsWith("-")){
            adName = adName.substring(0,adName.length()-1);
        }
        return adName;
    }


    private Long getCampaignId(AiBytedanceAdvertiserStrategy strategy, String campaignName,CtopOauthToken token) {
        ByteDanceCampaign campaign = campaignService.getOneByParams(strategy.getAccountId(),campaignName);
        if(null != campaign){
            return campaign.getId();
        }
        //创建组信息
        JSONObject campaignParam = new JSONObject();
        campaignParam.put("advertiser_id",strategy.getAccountId());
        campaignParam.put("campaign_name",campaignName);
        campaignParam.put("landing_type",strategy.getCampaignLandingType());
        if(null==strategy.getCampaignBudgetMode()|| "".equals(strategy.getCampaignBudgetMode())){
            campaignParam.put("budget_mode","BUDGET_MODE_INFINITE");
        }else{
            campaignParam.put("budget_mode",strategy.getCampaignBudgetMode());
        }
        //日预算必须设定预算金额
        if(null!=strategy.getCampaignBudgetMode()&& "BUDGET_MODE_DAY".equals(strategy.getCampaignBudgetMode())){
            campaignParam.put("budget",strategy.getCampaignBudget());
        }
        if(null != strategy.getCampaignDeliveryRelatedNum()||!"".equals(strategy.getCampaignDeliveryRelatedNum().trim())){
            campaignParam.put("delivery_related_num",strategy.getCampaignDeliveryRelatedNum());
        }
        //创建组
        Result campaignData = marketingService.createCampaign(token, campaignParam);
        if(campaignData.getCode()!=0){
            //TODO 组创建异常 后续需要加日志
            return null;
        }
        return (Long)campaignData.getResult();
    }

    private String getCampaignName(AiBytedanceAdvertiserStrategy strategy,Long dplinkIndex) {
        String campaignSufix = getRangeIndex(strategy.getDpLinkStartIndex(),strategy.getDpLinkEndIndex(),strategy.getCampaignAdCnt(),dplinkIndex);
        return strategy.getCampaignName()+campaignSufix;
    }

    private String getRangeIndex(Long dpLinkStartIndex,Long dpLinkEndIndex, Long campaignAdCnt, Long dpIndex) {
        if(dpIndex<dpLinkStartIndex||dpIndex>dpLinkEndIndex){
            //超出下标范围
            return null;
        }
        Long startIndex ;
        Long endIndex ;
        //计算当前下标值和范围区段的余数
        Long yzIndex = (dpIndex-dpLinkStartIndex+1)%campaignAdCnt;
        if(yzIndex == 0){
            startIndex = dpIndex-campaignAdCnt+1;
            endIndex = dpIndex;
        }else{
            startIndex = dpIndex-yzIndex+1;
            endIndex = dpIndex-yzIndex+campaignAdCnt;
        }
        return "-("+startIndex+"/"+endIndex+")";
    }

    private List<ByteDanceVideoInfo> getVideoInfoByCreateType(Long projectId,AiBytedanceAdvertiserStrategy strategy, String startTime, String endTime, Integer createType, Long videoCnt) {
        //1：上新素材 2：跑量素材 3：遗漏素材 4：打捞素材
        if(createType == 1||createType == 3){
            return videoInfoService.listByParams(strategy.getAccountId(),startTime,endTime,videoCnt,0);
        }else if(createType == 2){
            startTime = startTime.substring(0,10);
            endTime = endTime.substring(0,10);
            return videoInfoService.topMatByParams(projectId,strategy.getAccountId(),startTime,endTime,videoCnt);
        }else if(createType == 4){
            return videoInfoService.listByParams(strategy.getAccountId(),startTime,endTime,videoCnt,20);
        }
        return null;
    }
    /**
     *  修改状态 (0开-1关)
     *  同一账户下只能有一条数据信息为开启，可以全部关闭
     * @param
     * @return
     */
    @Override
    @Transactional
    public Result updStaById(String id,String state,String accountId) {
        //开启
        if (org.apache.commons.lang3.StringUtils.equals(state,"0")){
            //修改状态为开启
            aiBytedanceAdvertiserStrategyMapper.updStaById(id,state);
            //关闭 账户下 其他数据信息（不包含本条id信息） 状态为 关闭
            aiBytedanceAdvertiserStrategyMapper.updStaByAccountId(accountId,"1",id);
        }
        //关闭
        if (org.apache.commons.lang3.StringUtils.equals(state,"1")){
            // 修改 账户下 状态 为关闭
            aiBytedanceAdvertiserStrategyMapper.updStaById(id,state);
        }

        return Result.successMsg("状态修改成功---》"+("0".equals(state) ? "开" : "关"), null);
    }


    /**
     * 头条 - 配置信息 修改 出价; 预算;
     * @param updAdStaOrCpaOrBudget
     * @return
     */
    @Override
    public Result updStaOrCpaOrBudgetById(UpdAdStaOrCpaOrBudget updAdStaOrCpaOrBudget) {
        //1-修改出价
        if (BytedanceConstant.UPDTYPE_BID.equals(updAdStaOrCpaOrBudget.getType())) {
            aiBytedanceAdvertiserStrategyMapper.updCpaById(updAdStaOrCpaOrBudget);
        }
        //2-修改预算
        if (BytedanceConstant.UPDTYPE_BUDGET.equals(updAdStaOrCpaOrBudget.getType())) {
            if (new BigDecimal(updAdStaOrCpaOrBudget.getBudget()).compareTo(updAdStaOrCpaOrBudget.getCost().multiply(new BigDecimal(1.05))) == -1){
                return Result.errorMsg("修改后预算金额不能低于当前已消费金额的105%");
            }
            aiBytedanceAdvertiserStrategyMapper.updBudgetById(updAdStaOrCpaOrBudget.getId(), updAdStaOrCpaOrBudget.getBudget());

        }
        return Result.successMsg("修改"+(BytedanceConstant.UPDTYPE_BID.equals(updAdStaOrCpaOrBudget.getType()) ? "出价" : "预算")+"成功。",null);
    }



    /**
     *
     * 获取行业类别
     * @param accountId 广告主id
     * @param type 行业类别
     * @return org.jeecg.common.api.vo.Result
     * @author zianY
     */
    @Override
    public Result getIndustryList(String accountId, String type) throws Exception {
        CtopOauthToken token = tokenService.getOauthTokenByAccountId(accountId);
        if (null == token) {
            log.info("token获取失败=>accountId:{}", accountId);
            return Result.error("token获取失败====>>>>accountId:"+accountId);
        }
        // api 获取行业列表
        Result listResult = marketingService.getToolIndustryList(token,type);
        List<Map<String,Object>> industryListMap = (List<Map<String,Object>>) listResult.getResult();
        // list map 数据格式 转 list entity 数据格式
        List<IndustryVo> industryList = Check.convertListMap2ListBean(industryListMap,IndustryVo.class);
        //所有行业分类 设置 父id
        industryList.forEach(industryVo -> {
            if ("1".equals(industryVo.getLevel())){
                industryVo.setPId("0");
            }
            if ("2".equals(industryVo.getLevel())){
                industryVo.setPId(industryVo.getFirst_industry_id());
            }
            if ("3".equals(industryVo.getLevel())){
                industryVo.setPId(industryVo.getSecond_industry_id());
            }
        });

        //行业分类 层级展示
        List<Map<String,Object>> classificationVos = treeCategoryData(industryList,"0");
        return Result.successMsg("获取行业列表成功。",classificationVos);

    }

    /**
     * 递归 行业分类 tree 层级展示
     * @param allList
     * @param parentId
     * @return
     */
    public List<Map<String,Object>> treeCategoryData(List<IndustryVo> allList, String parentId) {
        List<Map<String,Object>> mapList = new ArrayList<>();
        for (IndustryVo vo : allList) {
            if (parentId.equals(vo.getPId())){
                Map<String,Object> map = new HashMap<>();
                map.put("industryId", vo.getIndustry_id());
                map.put("industryName", vo.getIndustry_name());
                map.put("level", vo.getLevel());
                map.put("pId", vo.getPId());
                map.put("children", treeCategoryData(allList,vo.getIndustry_id()));
                mapList.add(map);
            }
        }
        return mapList;

    }



    /**
     *
     * 获取广告组
     *
     * @param accountId 广告主id
     * @param adGroupSearchVoList
     * @param pageNo
     * @param pageSize
     * @return org.jeecg.common.api.vo.Result
     * @author zianY
     */
    @Override
    public Result getCampaignGroup(String accountId, List<AdGroupSearchVo> adGroupSearchVoList, Integer pageNo, Integer pageSize) {

        CtopOauthToken token = tokenService.getOauthTokenByAccountId(accountId);
        if (null == token) {
            log.info("token获取失败=>accountId:{}", accountId);
            return Result.error("token获取失败====>>>>accountId:"+accountId);
        }
        // 获取广告组
        Result industryList = marketingService.getCampaignGroupList(token,accountId,null,pageNo,pageSize);
        log.error("获取广告组=======>>>>>>>>>>>{}", industryList.getResult());
        return Result.successMsg("获取广告组成功。", industryList.getResult());
    }



    /**
     *
     * 获取广告计划
     *
     * @param accountId 广告主id
     * @param adGroupSearchVoList 计划参数
     * @param pageNo 页数
     * @param pageSize 每页条数
     * @return org.jeecg.common.api.vo.Result
     * @author zianY
     */
    @Override
    public Result getCampaignPlan(String accountId, List<PlanSearchVo> adGroupSearchVoList, Integer pageNo, Integer pageSize) {

        CtopOauthToken token = tokenService.getOauthTokenByAccountId(accountId);
        if (null == token) {
            log.info("token获取失败=>accountId:{}", accountId);
            return Result.error("token获取失败====>>>>accountId:"+accountId );
        }
        // 获取计划
        Result industryList = marketingService.getPlanList(token,adGroupSearchVoList,pageNo,pageSize);
        log.error("获取广告计划=======>>>>>>>>>>>{}", industryList.getResult());
        return Result.successMsg("获取广告计划成功。", industryList.getResult());
    }

    /**
     *
     * 获取创意详细信息
     *
     * @param accountId 广告主id
     * @param adId 计划id
     * @return org.jeecg.common.api.vo.Result
     * @author zianY
     */
    @Override
    public Result creativeReadInfo(String accountId, String adId) {
        CtopOauthToken token = tokenService.getOauthTokenByAccountId(accountId);
        if (null == token) {
            log.info("token获取失败=>accountId:{}", accountId);
            return Result.error("token获取失败====>>>>accountId:"+accountId);
        }
        // 获取 创意详细信息
        Result industryList = marketingService.creativeRead(token,accountId,adId);
        log.error("获取创意详细信息=======>>>>>>>>>>>{}", industryList.getResult());
        return Result.successMsg("获取创意详细信息成功。", industryList.getResult());
    }
    /**
     *
     * 修改 广告 组-计划-创意
     *
     * @param strategy
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     */
    @Override
    public Result updateADCreative(AiBytedanceAdvertiserStrategy strategy, String groupModifyTime, String planModifyTime) {

        CtopOauthToken token = tokenService.getOauthTokenByAccountId(strategy.getAccountId()+"");
        if (null == token) {
            log.info("token获取失败=>accountId:{}", strategy.getAccountId());
            return Result.error("token获取失败====>>>>accountId:"+strategy.getAccountId());
        }
        // 1:修改广告组
        Result resultCampaign = marketingService.updateCampaign(token,
                "广告组id",groupModifyTime,
                strategy.getCampaignName(),strategy.getCampaignBudgetMode(),strategy.getCampaignLandingType());
        //广告组id
        Long campaignId = (Long) resultCampaign.getResult();
        // 2:修改广告计划
        Result resultPlan = marketingService.updateAdvertiserPlan(token,"计划id",planModifyTime,strategy);
        //计划id
        Object planId = resultPlan.getResult();
        //3:修改创意 TODO 拼接创意参数
        Result creativeInfo = marketingService.creativeUpdate(token, "计划id","创意时间戳",null);
        //数据修改
        aiBytedanceAdvertiserStrategyMapper.updateById(strategy);
        return Result.successMsg("修改成功", strategy);
    }


    /**
     *
     * @description: 查询广告计划可用转化目标
     *
     * @param adConvertQueryVo
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     */
    @Override
    public Result getToolConvert(AdConvertQueryVo adConvertQueryVo) {
        CtopOauthToken token = tokenService.getOauthTokenByAccountId(adConvertQueryVo.getAdvertiserId());
        if (null == token) {
            log.info("token获取失败=>accountId:{}", token.getAccountId());
            return Result.error("token获取失败====>>>>accountId:"+token.getAccountId());
        }
        return marketingService.getToolConvertQuery(token,adConvertQueryVo);
    }


    /**
     *
     * @description: 添加配置信息
     *
     * @param aiBytedanceAdvertiserStrategy
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     */
    @Override
    public Result addBytedanceStrategy(AiBytedanceAdvertiserStrategy aiBytedanceAdvertiserStrategy) {
        // 数据入库 string[] 转 string
        //商品卖点
        aiBytedanceAdvertiserStrategy.setCreativeProductSellingPoints(org.apache.commons.lang3.StringUtils.join(aiBytedanceAdvertiserStrategy.getProductSellingPoints(), ","));
        //广告位置
        aiBytedanceAdvertiserStrategy.setCreativeInventoryType(org.apache.commons.lang3.StringUtils.join(aiBytedanceAdvertiserStrategy.getCreativeInventoryTypes(), ","));
        //创意标签
        aiBytedanceAdvertiserStrategy.setCreativeAdKeywords(org.apache.commons.lang3.StringUtils.join(aiBytedanceAdvertiserStrategy.getAdKeywords(), ","));
        aiBytedanceAdvertiserStrategy.setCreateTime(new Date());

        //同一账户下 只能有一条信息 为开启
        //关闭 账户下 其他数据信息（不包含本条id信息） 状态为 关闭
        aiBytedanceAdvertiserStrategyMapper.updStaByAccountId(String.valueOf(aiBytedanceAdvertiserStrategy.getAccountId()),"1",null);
        //状态（0开 1关）
        aiBytedanceAdvertiserStrategy.setStatus(0);

        //添加素材信息
        MaterialImageInfo imageInfo = new MaterialImageInfo();
        imageInfo.setUrl(aiBytedanceAdvertiserStrategy.getImageUrl());
        imageInfo.setUserId(aiBytedanceAdvertiserStrategy.getUserId());
        materialImageInfoService.initImageCode(imageInfo);

        aiBytedanceAdvertiserStrategyMapper.insert(aiBytedanceAdvertiserStrategy);

        return Result.successMsg("新增成功。",aiBytedanceAdvertiserStrategy);
    }

    @Override
    public List<AiBytedanceAdvertiserStrategy> getByAccountId(Long accountId,Integer status) {
        QueryWrapper<AiBytedanceAdvertiserStrategy> queryWrapper = new QueryWrapper<>();
        if(null!=accountId){
            queryWrapper.eq("account_id",accountId);
        }
        if(null!=status){
            queryWrapper.eq("status",status);
        }
        queryWrapper.orderByDesc("id");
        return this.list(queryWrapper);
    }

    @Autowired
    private IByteDanceAdvertisePlanService planService;
    @Override
    public void customCreativeSupplement(AiBytedanceAdvertiserStrategy strategy, Integer hour,String openUrl) {
        Long customUnitCnt = strategy.getCampaignAdCnt()*strategy.getCampaignCnt();
        Long unitNum = customUnitCnt * hour / 15;
        log.info("{}当前时间内需要创建计划总数：{}", strategy.getAccountId(), unitNum);
        //查询当前账户创建自定义类型计划数量
        int unitCreateCnt = planService.queryToDayBuiltCount(strategy.getAccountId());
        log.info("{}截止目前创建组总数：{}", strategy.getAccountId(), unitCreateCnt);
        long remindCnt = unitNum - unitCreateCnt;
        if (remindCnt >= 1) {
            log.info("{}计划创建不足，剩余需要创建个数{},使用历史遗漏素材创建", strategy.getAccountId(), remindCnt);
            //优先创建历史遗漏素材
            remindCnt = this.createCreative(strategy, 3, remindCnt,openUrl);
        }
        if (remindCnt >= 1) {
            log.info("{}计划创建不足，剩余需要创建个数{},使用高质量素材创建", strategy.getAccountId(), remindCnt);
            //高质量素材
            remindCnt = this.createCreative(strategy, 2, remindCnt,openUrl);
        }
        if (remindCnt >= 1) {
            //历史打捞素材
            log.info("{}计划创建不足，剩余需要创建个数{},使用历史打捞素材创建", strategy.getAccountId(), remindCnt);
            this.createCreative(strategy, 4, remindCnt,openUrl);
        }
    }



    /**
     *
     * 获取行动号召
     *
     * @param accountId
     * @param landingType
     * @param advancedCreativeType
     * @return org.jeecg.common.api.vo.Result
     * @author zianY
     */
    @Override
    public Result getAdActionText(String accountId, String landingType, String advancedCreativeType) throws Exception{
        CtopOauthToken token = tokenService.getOauthTokenByAccountId(accountId);
       return marketingService.getActionText(token,landingType,advancedCreativeType);
    }


    @Resource
    private BytedanceAreaInfoMapper bytedanceAreaInfoMapper;

    /**
     *
     * @description: 获取定向包
     *
     * @param accountId 广告主id
     * @param landingType 投放目标
     * @param deliveryRange
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     */
    @Override
    public Result getAdAudiencePackage(String accountId, String landingType, String deliveryRange){
       CtopOauthToken token = tokenService.getOauthTokenByAccountId(accountId);
        //查询定向包信息
       Result list = marketingService.getAudiencePackage(token,landingType,deliveryRange);
       //处理返回结果
       JSONObject jsonObject = (JSONObject)list.getResult();
       JSONArray array = jsonObject.getJSONArray("audience_packages");
        List<Map<String,JSONObject>> dataList = JSONArray.parseObject(array.toJSONString(),List.class);
        dataList.forEach(map -> {
            JSONObject audience = map.get("audience");
            //性别
            String gender = audience.getString("gender");
            if (Check.isNull(gender)){
                audience.put("gender", "NONE");
            }
            //返回结果中的city 查询 城市名称
            JSONArray citys = audience.getJSONArray("city");
            if (citys != null){
                QueryWrapper<BytedanceAreaInfo> queryWrapper = new QueryWrapper<>();
                queryWrapper.in("code", citys);
                List<BytedanceAreaInfo> cityList = bytedanceAreaInfoMapper.selectList(queryWrapper);
                List<String> cityStr = cityList.stream().map(BytedanceAreaInfo::getName).collect(Collectors.toList());
                audience.put("cityNames",cityStr);
            }
        });
        return Result.successMsg("成功。",dataList);
    }

    /**
     *
     * @description: 获取人群包列表信息
     *
     * @param accountId
     * @return: org.jeecg.common.api.vo.Result
     * @author: zianY
     */
    @Override
    public Result getDMPCustomAudience(String accountId){

        CtopOauthToken token = tokenService.getOauthTokenByAccountId(accountId);
        // 获取人群包列表
       Result list = marketingService.selectCustomAudience(token);
       if (!list.isSuccess()){
           return Result.errorMsg(list.getMessage());
       }
        //List<Map<String,Object>> listMap = (List<Map<String, Object>>) list.getResult();
        JSONArray array =(JSONArray)list.getResult();
        List<Map<String,Object>> dataList = JSONArray.parseObject(array.toJSONString(),List.class);
        //获取人群包id  List
        List<Object> packageList = dataList.stream().map(map -> map.get("custom_audience_id")).collect(Collectors.toList());
        String idStr = Joiner.on(",").join(packageList);
        List<Integer> idsIntList = Arrays.asList(idStr.split(",")).stream().map(id -> Integer.valueOf(id.trim())).collect(Collectors.toList());
        //获取人群包详细信息
        Result packageInfoList = marketingService.getAudiencePackageRead(token,accountId,idsIntList);
        List<Map<String,Object>> listInfoMap = (List<Map<String, Object>>) packageInfoList.getResult();
        //人群包是否被删除 "1"：已删除，"0"：未删除
        //人群包可投放状态，只有当状态为CUSTOM_AUDIENCE_DELIVERY_STATUS_AVAILABLE时才可进行投放使用
        List<Map<String,Object>> filterList = listInfoMap.stream()
                .filter(info -> Integer.valueOf(info.get("isdel")+"") == 0)
                .filter(info -> "CUSTOM_AUDIENCE_DELIVERY_STATUS_AVAILABLE".equalsIgnoreCase(info.get("delivery_status")+""))
                .collect(Collectors.toList());
        return Result.successMsg("人群包获取成功。",filterList);
    }


    public Result createAudiencePackage(String accountId){

        CtopOauthToken token = tokenService.getOauthTokenByAccountId(accountId);

       Result list = marketingService.createAudiencePackage(token);

        return Result.successMsg("定向包创建成功。",list);
    }


}
