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

import cn.com.ctop.common.module.entity.CtopOauthToken;
import cn.com.ctop.common.module.service.ICtopOauthTokenService;
import cn.com.ctop.common.module.utils.Check;
import cn.com.ctop.common.module.utils.HttpUtils;
import cn.com.ctop.kuaishou.modules.hosting.entity.KuaishouHostingTask;
import cn.com.ctop.kuaishou.modules.hosting.entity.KuaishouHostingTemplate;
import cn.com.ctop.kuaishou.modules.hosting.mapper.KuaishouHostingTaskMapper;
import cn.com.ctop.kuaishou.modules.hosting.service.IKuaishouHostingTaskService;
import cn.com.ctop.kuaishou.modules.hosting.service.IKuaishouHostingTemplateService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 智能托管-任务详情
 *
 * @author jeecg-boot
 * 2021-11-09
 * @version V1.0
 */
@Slf4j
@Service
public class KuaishouHostingTaskServiceImpl extends ServiceImpl<KuaishouHostingTaskMapper, KuaishouHostingTask> implements IKuaishouHostingTaskService {
    @Autowired
    private IKuaishouHostingTemplateService hostingTemplateService;
    @Autowired
    private RedisUtil redisUtil;
    private static String hostingKey = "hosting";
    @Autowired
    private KuaishouHostingTaskMapper hostingTaskMapper;
    @Autowired
    private ICtopOauthTokenService tokenService;
    private HashMap<Integer, JSONObject> ageMap = new HashMap<>();

    @Override
    public void submitTask(Long templateId, JSONArray videoArray) throws Exception {
        KuaishouHostingTemplate template = hostingTemplateService.getById(templateId);
        if (Check.isNull(template)) {
            throw new Exception("未匹配到模板信息");
        }

        //  投放时段前端传值问题，需要单独处理
        String schedule = template.getSchedule();
        JSONArray scheduleArray = new JSONArray();
        if (!Check.isNull(schedule)) {
            JSONArray array = JSONArray.parseArray(schedule);
            if (!Check.isNull(array)) {
                for (int i = 0; i < array.size(); i++) {
                    JSONArray jsonArray = array.getJSONArray(i);
                    JSONArray addArray = new JSONArray();
                    for (int j = 0; j < jsonArray.size(); j++) {
                        Integer value = jsonArray.getInteger(j);
                        if (Check.isNull(value)) {
                            continue;
                        }
                        addArray.add(value);
                    }
                    scheduleArray.add(addArray);
                }
            }
        }
        List<List<Object>> videoList = Lists.partition(videoArray, template.getVideoCount());
        List<KuaishouHostingTask> addList = new ArrayList<>();
        for (int i = 0; i < videoList.size(); i++) {
            List<Object> videoInfo = videoList.get(i);
            if (Check.isNull(videoInfo)) {
                continue;
            }
            KuaishouHostingTask task = new KuaishouHostingTask();
            task.setTemplateId(templateId);
            task.setAccountId(template.getAccountId());
            task.setTaskStatus(1);
            task.setRemarks("待创建");
            task.setPhotoInfos(videoInfo.toString());
            task.setName(getName(template.getName(), task.getAccountId()));
            task.setHostingScene(template.getHostingScene());
            String sceneIds = template.getSceneIds();
            if (!Check.isNull(sceneIds)) {
                task.setSceneIds(sceneIds);
            }
            task.setCampaignType(template.getCampaignType());
            if (!Check.isNull(template.getAppId())) {
                task.setAppId(template.getAppId());
            }
            if (!Check.isNull(template.getWebUri())) {
                task.setWebUri(template.getWebUri());
            }
            task.setUseAppMarket(template.getUseAppMarket());
            if (!Check.isNull(template.getAppStore())) {
                task.setAppStore(template.getAppStore());
            }
            if (!Check.isNull(template.getStickerStyles())) {
                task.setStickerStyles(template.getStickerStyles());
            }
            if (!Check.isNull(template.getCoverSlogans())) {
                task.setCoverSlogans(template.getCoverSlogans());
            }
            task.setActionBar(template.getActionBar());
            task.setCaptions(template.getCaptions());
            task.setClickUrl(template.getClickUrl());
            task.setActionbarClickUrl(template.getActionbarClickUrl());
            task.setAutoCreatePhoto(template.getAutoCreatePhoto());
            task.setSchedule(scheduleArray.toJSONString());
            task.setDayBudget(template.getDayBudget());
            task.setOcpxActionType(template.getOcpxActionType());
            task.setCpaBid(template.getCpaBid());
            if (!Check.isNull(template.getDeepConversionType())) {
                task.setDeepConversionType(template.getDeepConversionType());
            }
            if (!Check.isNull(template.getDeepConversionBid())) {
                task.setDeepConversionBid(template.getDeepConversionBid());
            }
            if (!Check.isNull(template.getSiteId())) {
                task.setSiteId(template.getSiteId());
            }
            task.setSmartCover(template.getSmartCover());
            if (!Check.isNull(template.getRoiRatio())) {
                task.setRoiRatio(template.getRoiRatio());
            }
            if (!Check.isNull(template.getConsultId())) {
                task.setConsultId(template.getConsultId());
            }
            if (!Check.isNull(template.getMerchandiseId())) {
                task.setMerchandiseId(template.getMerchandiseId());
            }
            if (!Check.isNull(template.getMerchandiseType())) {
                task.setMerchandiseType(template.getMerchandiseType());
            }
            task.setAssetMining(template.getAssetMining());
            task.setFictionId(template.getFictionId());
            task.setWebUriType(template.getWebUriType());
            task.setMaxAge(template.getMaxAge());
            task.setMinAge(template.getMinAge());
            task.setAgesRange(template.getAgesRange());
            task.setPopulation(template.getPopulation());
            task.setExcludePopulation(template.getExcludePopulation());
            task.setPaidAudience(template.getPaidAudience());
            task.setGender(template.getGender());
            task.setRegionIds(template.getRegionIds());
            task.setUserType(template.getUserType());
            task.setIsOpen(template.getIsOpen());
            task.setNoAgeBreak(template.getNoAgeBreak());
            task.setNoGenderBreak(template.getNoGenderBreak());
            task.setNoAreaBreak(template.getNoAreaBreak());
            task.setPlatformOs(template.getPlatformOs());
            task.setPlatformOv(template.getPlatformOv());
            task.setFilterConvertedLevel(template.getFilterConvertedLevel());
            task.setRuleEnable(template.getRuleEnable());
            if (!Check.isNull(template.getCampaignNameRule())) {
                task.setCampaignNameRule(getCampaignName(template.getCampaignNameRule(), task.getAccountId()));
            }
            task.setUnitNameRule(template.getUnitNameRule());
            task.setCreativeNameRule(template.getCreativeNameRule());
            addList.add(task);
        }
        if (!Check.isNull(addList)) {
            hostingTaskMapper.addBatch(addList);
        }
    }


    @Override
    public void createHosting(Long id) {
        try {
            KuaishouHostingTask task = hostingTaskMapper.selectById(id);
            if (Check.isNull(task)) {
                log.error("未获取到智能托管创建详情，id：{}", id);
                return;
            }
            String photoInfos = task.getPhotoInfos();
            JSONArray photoArray = JSONArray.parseArray(photoInfos);
            if (Check.isNull(photoArray)) {
                hostingTaskMapper.updateStatusById(task.getId(), 4, "未获取到视频信息");
                log.error("未获取到视频信息,id:{}", id);
                return;
            }
            CtopOauthToken token = tokenService.getTokenByAccountId(task.getAccountId());
            if (Check.isNull(token)) {
                hostingTaskMapper.updateStatusById(task.getId(), 4, "未获取到账户授权信息");
                log.error("智能托管未获取到相关token,accountId:{}", task.getAccountId());
                return;
            }
            JSONObject requestJson = new JSONObject();
            requestJson.put("advertiser_id", task.getAccountId());
            requestJson.put("name", task.getName());
            requestJson.put("hosting_scene", task.getHostingScene());

            String sceneIds = task.getSceneIds();
            if (!Check.isNull(sceneIds)) {
                JSONArray scene_ids = JSONArray.parseArray(sceneIds);
                if (!Check.isNull(scene_ids)) {
                    requestJson.put("scene_ids", scene_ids);
                }
            }
            requestJson.put("campaign_type", task.getCampaignType());
            if (!Check.isNull(task.getAppId())) {
                requestJson.put("app_id", task.getAppId());
            }
            if (!Check.isNull(task.getWebUri())) {
                requestJson.put("web_uri", task.getWebUri());
            }
            if (task.getUseAppMarket() == 1) {
                requestJson.put("use_app_market", true);
                if (!Check.isNull(task.getAppStore())) {
                    requestJson.put("app_store", JSONArray.parseArray(task.getAppStore()));
                }
            } else {
                requestJson.put("use_app_market", false);
            }
            if (!Check.isNull(task.getStickerStyles())) {
                requestJson.put("sticker_styles", JSONArray.parseArray(task.getStickerStyles()));
            }
            if (!Check.isNull(task.getCoverSlogans())) {
                requestJson.put("cover_slogans", JSONArray.parseArray(task.getCoverSlogans()));
            }
            requestJson.put("action_bar", task.getActionBar());
            if (!Check.isNull(task.getCaptions())) {
                requestJson.put("captions", JSONArray.parseArray(task.getCaptions()));
            }
            requestJson.put("click_url", task.getClickUrl());
            if (!Check.isNull(task.getActionbarClickUrl())) {
                requestJson.put("actionbar_click_url", task.getActionbarClickUrl());
            }
            if (!Check.isNull(task.getAutoCreatePhoto())) {
                if (task.getAutoCreatePhoto() == 1) {
                    requestJson.put("auto_create_photo", true);
                } else {
                    requestJson.put("auto_create_photo", false);
                }
            } else {
                requestJson.put("auto_create_photo", false);
            }

            Long begin_time = System.currentTimeMillis();
            requestJson.put("begin_time", begin_time);
            requestJson.put("end_time", 0);
            if (!Check.isNull(task.getSchedule())) {
                requestJson.put("schedule", task.getSchedule());
            }
            requestJson.put("day_budget", task.getDayBudget());
            requestJson.put("ocpx_action_type", task.getOcpxActionType());
            requestJson.put("cpa_bid", task.getCpaBid());
            if (!Check.isNull(task.getDeepConversionType())) {
                requestJson.put("deep_conversion_type", task.getDeepConversionType());
            }
            if (!Check.isNull(task.getDeepConversionBid())) {
                requestJson.put("deep_conversion_bid", task.getDeepConversionBid());
            }
            if (!Check.isNull(task.getSiteId())) {
                requestJson.put("site_id", task.getSiteId());
            }
            if (task.getSmartCover() == 1) {
                requestJson.put("smart_cover", true);
            } else {
                requestJson.put("smart_cover", false);
            }
            if (!Check.isNull(task.getRoiRatio())) {
                requestJson.put("roi_ratio", task.getRoiRatio());
            }
            if (!Check.isNull(task.getConsultId())) {
                requestJson.put("consult_id", task.getConsultId());
            }
            if (!Check.isNull(task.getMerchandiseId())) {
                requestJson.put("merchandise_id", task.getMerchandiseId());
            }
            if (!Check.isNull(task.getMerchandiseType())) {
                requestJson.put("merchandise_type", task.getMerchandiseType());
            }
            if (task.getAssetMining() == 1) {
                requestJson.put("asset_mining", true);
            } else {
                requestJson.put("asset_mining", false);
            }
            if (!Check.isNull(task.getFictionId())) {
                requestJson.put("fiction_id", task.getFictionId());
            }
            if (!Check.isNull(task.getWebUriType())) {
                requestJson.put("web_uri_type", task.getWebUriType());
            }
            /*---------    命名规则  ---------*/
            JSONObject nameRule = new JSONObject();
            if (task.getRuleEnable() == 1) {
                nameRule.put("rule_enable", true);
                if (!Check.isNull(task.getCampaignNameRule())) {
                    nameRule.put("campaign_name_rule", task.getCampaignNameRule());
                }
                if (!Check.isNull(task.getUnitNameRule())) {
                    nameRule.put("unit_name_rule", task.getUnitNameRule());
                }
                if (!Check.isNull(task.getCreativeNameRule())) {
                    nameRule.put("creative_name_rule", task.getCreativeNameRule());
                }
            } else {
                nameRule.put("rule_enable", false);
            }
            requestJson.put("name_rule", nameRule);
            /*---------    定向拼接  ---------*/
            JSONObject adDspTarget = new JSONObject();
            Integer minAge = task.getMinAge();
            Integer maxAge = task.getMaxAge();
            JSONArray ageArray = new JSONArray();
            if (!Check.isNull(minAge) && !Check.isNull(maxAge)) {
                if (maxAge != -1 && minAge != -1) {
                    JSONObject ageJson = new JSONObject();
                    ageJson.put("min", minAge);
                    ageJson.put("max", maxAge);
                    ageArray.add(ageJson);
                } else {
                    String agesRange = task.getAgesRange();
                    JSONArray agesRangeArray = JSONArray.parseArray(agesRange);
                    if (!Check.isNull(agesRangeArray)) {
                        ageArray = getAgeArray(agesRangeArray);
                    }
                }
            } else {
                String agesRange = task.getAgesRange();
                JSONArray agesRangeArray = JSONArray.parseArray(agesRange);
                if (!Check.isNull(agesRangeArray)) {
                    ageArray = getAgeArray(agesRangeArray);
                }
            }
            adDspTarget.put("age", ageArray);
            if (!Check.isNull(task.getPopulation())) {
                adDspTarget.put("population", JSONArray.parseArray(task.getPopulation()));
            }
            if (!Check.isNull(task.getExcludePopulation())) {
                adDspTarget.put("exclude_population", JSONArray.parseArray(task.getExcludePopulation()));
            }
            if (!Check.isNull(task.getPaidAudience())) {
                adDspTarget.put("paid_audience", JSONArray.parseArray(task.getPaidAudience()));
            }
            String gender = task.getGender();
            if (!Check.isNull(gender)) {
                adDspTarget.put("gender", gender);
            }
            if (!Check.isNull(task.getRegionIds())) {
                adDspTarget.put("region_ids", JSONArray.parseArray(task.getRegionIds()));
                if (!Check.isNull(JSONArray.parseArray(task.getRegionIds()))) {
                    adDspTarget.put("user_type", task.getUserType());
                }
            }
            if (task.getIsOpen() == 1) {
                JSONObject intelliExtend = new JSONObject();
                intelliExtend.put("is_open", task.getIsOpen());
                if (task.getNoAgeBreak() == 1) {
                    intelliExtend.put("no_age_break", true);
                } else {
                    intelliExtend.put("no_age_break", false);
                }
                if (task.getNoGenderBreak() == 1) {
                    intelliExtend.put("no_gender_break", true);
                } else {
                    intelliExtend.put("no_gender_break", false);
                }
                if (task.getNoAreaBreak() == 1) {
                    intelliExtend.put("no_area_break", true);
                } else {
                    intelliExtend.put("no_area_break", false);
                }
                adDspTarget.put("intelli_extend", intelliExtend);
            }
            Integer platformOs = task.getPlatformOs();
            if (platformOs != 3) {
                String platformStr = null;
                if (platformOs == 1) {
                    platformStr = "android";
                } else if (platformOs == 2) {
                    platformStr = "ios";
                }
                JSONObject platformJson = new JSONObject();
                JSONObject ovJson = new JSONObject();
                ovJson.put("min", task.getPlatformOv());
                platformJson.put(platformStr, ovJson);
                adDspTarget.put("platform", platformJson);
            } else {
                adDspTarget.put("platform", "{}");
            }
            adDspTarget.put("filter_converted_level", task.getFilterConvertedLevel());
            requestJson.put("ad_dsp_target", adDspTarget);
            /*---------    视频组装  ---------*/
            JSONArray videoInfo = getPhotoArray(photoArray);
            requestJson.put("photo_infos", videoInfo);
            log.info("创建智能托管,accountId:{},入参：{}", task.getAccountId(), requestJson);
            JSONObject hosting = createHosting(task.getAccountId(), token.getAccessToken(), requestJson);
            if (!Check.isNull(hosting)) {
                Integer code = hosting.getInteger("code");
                Long projectId = null;
                Long campaignId = null;
                if (code == 0) {
                    log.info("智能托管创建成功，accountId:{}，返回信息：{}", task.getAccountId(), hosting);
                    JSONObject data = hosting.getJSONObject("data");
                    if (!Check.isNull(data)) {
                        projectId = data.getLong("project_id");
                        if (!Check.isNull(projectId)) {
                            campaignId = getProjectDetail(task.getAccountId(), token.getAccessToken(), projectId);
                        }
                    }
                    hostingTaskMapper.updateInfoById(task.getId(), projectId, campaignId, 3, "创建成功");
                } else {
                    log.error("智能托管创建失败，accountId:{},入参：{},返回：{}", task.getAccountId(), requestJson, hosting);
                    hostingTaskMapper.updateStatusById(task.getId(), 4, hosting.getString("message"));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            hostingTaskMapper.updateStatusById(id, 4, e.getMessage());
        }
    }

    @Override
    public void updateStatusById(Long id, Integer taskStatus, String remarks) {
        hostingTaskMapper.updateStatusById(id, taskStatus, remarks);
    }

    private String getName(String name, Long accountId) {
        String nowDate = DateUtils.getNowDate("yyyy-MM-dd").replace("-", "");
        String redisKey = hostingKey + "_" + nowDate + "_" + accountId;
        Object o = redisUtil.get(redisKey);
        Integer count;
        if (Check.isNull(o)) {
            count = 0;
            redisUtil.set(redisKey, 0, 86400L);
        } else {
            count = (Integer) o + 1;
            redisUtil.set(redisKey, count, 86400L);
        }
        return name + "_" + nowDate + "_" + count;
    }

    private String getCampaignName(String name, Long accountId) {
        String nowDate = DateUtils.getNowDate("yyyy-MM-dd").replace("-", "");
        String redisKey = hostingKey + "_" + nowDate + "_" + accountId;
        Object o = redisUtil.get(redisKey);
        Integer count;
        if (Check.isNull(o)) {
            count = 0;
        } else {
            count = (Integer) o;
        }
        return name + "_" + nowDate + "_" + count;
    }

    private JSONArray getAgeArray(JSONArray ageArray) {
        JSONArray returnArray = new JSONArray();
        if (Check.isNullMap(ageMap)) {
            JSONObject array18 = new JSONObject();
            array18.put("min", 18);
            array18.put("max", 23);
            ageMap.put(18, array18);

            JSONObject array24 = new JSONObject();
            array24.put("min", 24);
            array24.put("max", 30);
            ageMap.put(24, array24);

            JSONObject array31 = new JSONObject();
            array31.put("min", 31);
            array31.put("max", 40);
            ageMap.put(31, array31);

            JSONObject array41 = new JSONObject();
            array41.put("min", 41);
            array41.put("max", 49);
            ageMap.put(41, array41);

            JSONObject array50 = new JSONObject();
            array50.put("min", 50);
            array50.put("max", 100);
            ageMap.put(50, array50);
        }

        for (int i = 0; i < ageArray.size(); i++) {
            Integer age = ageArray.getInteger(i);
            returnArray.add(ageMap.get(age));
        }
        return returnArray;
    }

    private JSONArray getPhotoArray(JSONArray photoArray) {
        JSONArray videoArray = new JSONArray();
        for (int i = 0; i < photoArray.size(); i++) {
            Long photoId = photoArray.getLong(i);
            if (Check.isNull(photoId)) {
                continue;
            }
           /* Integer materialType = hostingTaskMapper.getMaterialType(photoId);
            if (Check.isNull(materialType)) {
                continue;
            }*/
            JSONObject videoJson = new JSONObject();
            videoJson.put("photo_id", photoId);
            videoJson.put("photo_orientation", 1);
            videoArray.add(videoJson);
        }
        return videoArray;
    }


    private JSONObject createHosting(Long accountId, String token, JSONObject requestJson) {
        String url = "https://ad.e.kuaishou.com/rest/openapi/gw/dsp/v1/hosting/project/create";
        Map<String, String> headers = new HashMap<String, String>();
        headers.put("Content-Type", "application/json");
        headers.put("Access-Token", token);
        String result = HttpUtils.kuaiShouhttpPostRequest(url, requestJson.toJSONString(), headers);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        JSONObject resultJson = JSONObject.parseObject(result);
        return resultJson;
    }


    private Long getProjectDetail(Long accountId, String token, Long projectId) {
        String url = "https://ad.e.kuaishou.com/rest/openapi/gw/dsp/v1/hosting/project/detail";
        Map<String, String> headers = new HashMap<String, String>();
        headers.put("Content-Type", "application/json");
        headers.put("Access-Token", token);
        JSONObject requestJson = new JSONObject();
        requestJson.put("project_id", projectId);
        requestJson.put("advertiser_id", accountId);
        String result = HttpUtils.kuaiShouhttpPostRequest(url, requestJson.toJSONString(), headers);
        JSONObject resultJson = JSONObject.parseObject(result);
        if (!Check.isNull(resultJson)) {
            Integer code = resultJson.getInteger("code");
            if (code == 0) {
                JSONObject data = resultJson.getJSONObject("data");
                if (!Check.isNull(data)) {
                    return data.getLong("campaign_id");
                }
            } else {
                log.error("获取智能托管详情数据失败，入参：{}，返回信息：{}", requestJson, resultJson);
                return null;
            }
        }
        return null;
    }
}
