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

import cn.com.ctop.common.module.entity.CtopOauthToken;
import cn.com.ctop.common.module.entity.MaterialCutFrame;
import cn.com.ctop.common.module.service.ICtopOauthTokenService;
import cn.com.ctop.common.module.service.IMaterialCutFrameService;
import cn.com.ctop.common.module.utils.Check;
import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouImageGet;
import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouVideoGet;
import cn.com.ctop.kuaishou.modules.batch.entity.KuaishouBatchCampaignPreview;
import cn.com.ctop.kuaishou.modules.batch.entity.KuaishouBatchCreativePreview;
import cn.com.ctop.kuaishou.modules.batch.entity.KuaishouBatchGroupPreview;
import cn.com.ctop.kuaishou.modules.batch.mapper.KuaishouBatchCampaignPreviewMapper;
import cn.com.ctop.kuaishou.modules.batch.mapper.KuaishouBatchCreativePreviewMapper;
import cn.com.ctop.kuaishou.modules.batch.mapper.KuaishouBatchGroupPreviewMapper;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouGroupTemplateService;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouImageGetService;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouMaterialUploadService;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouUpdateService;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouVideoGetService;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouBatchCreativePreviewService;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaishouInterfaceService;
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 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.ArrayList;
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 2021-01-26
 */
@Slf4j
@Service
public class KuaishouBatchCreativePreviewServiceImpl extends ServiceImpl<KuaishouBatchCreativePreviewMapper, KuaishouBatchCreativePreview> implements IKuaishouBatchCreativePreviewService {

    @Autowired
    KuaishouBatchCampaignPreviewMapper campaignPreviewMapper;
    @Autowired
    KuaishouBatchGroupPreviewMapper groupPreviewMapper;
    @Autowired
    KuaishouBatchCreativePreviewMapper creativePreviewMapper;

    @Autowired
    private IKuaishouInterfaceService kuaishouInterfaceService;
    @Autowired
    private ICtopOauthTokenService tokenService;
    @Autowired
    private IKuaiShouGroupTemplateService groupTemplateService;
    @Autowired
    private IKuaiShouVideoGetService videoGetService;
    @Autowired
    private IMaterialCutFrameService cutFrameService;
    @Autowired
    private IKuaiShouMaterialUploadService uploadService;
    @Autowired
    private IKuaiShouImageGetService imageGetService;
    @Autowired
    private IKuaiShouUpdateService kuaiShouUpdateService;
    static ExecutorService campaignService = Executors.newFixedThreadPool(10);
    static ExecutorService unitService = Executors.newFixedThreadPool(20);
    static ExecutorService creativeService = Executors.newFixedThreadPool(20);

    @Override
    public void createAdcampaignAndGroups(JSONObject data) throws Exception {
        Long accountId = data.getLong("accountId");
        JSONObject dataList = data.getJSONObject("dataList");
        if (!Check.isNull(dataList)) {
            List<String> compaignList = dataList.getJSONArray("campaigns").toJavaList(String.class);
            List<String> groupList = dataList.getJSONArray("groups").toJavaList(String.class);
            List<KuaishouBatchCampaignPreview> campaignPreviewList = campaignPreviewMapper.selectBatchIds(compaignList);
            List<KuaishouBatchGroupPreview> kuaishouBatchGroupPreviews = groupPreviewMapper.selectBatchIds(groupList);
            List<KuaishouBatchCreativePreview> kuaishouBatchCreativePreviews = creativePreviewMapper.selectBatchByUnitIds(groupList);
            //待建计划
            List<KuaishouBatchCampaignPreview> campaignList = getCampaignList(campaignPreviewList, kuaishouBatchGroupPreviews, kuaishouBatchCreativePreviews);
            CtopOauthToken oauthToken = tokenService.getTokenByAccountId(accountId);
            if (Check.isNull(oauthToken)) {
                throw new Exception("未获取到账户信息");
            }
            campaignList.forEach(campaign -> campaignService.submit(() -> {
                try {
                    creativeCampaign(oauthToken, campaign);
                } catch (Exception e) {
                    log.error("根据预览数据创建广告计划异常", e);
                }
            }));
        }
    }

    /**
     * 创建广告计划
     *
     * @param
     * @return void
     * @throws
     * @author ZHAOXA
     */
    private List<KuaishouBatchCampaignPreview> getCampaignList(List<KuaishouBatchCampaignPreview> campaignPreviewList, List<KuaishouBatchGroupPreview> kuaishouBatchGroupPreviews, List<KuaishouBatchCreativePreview> kuaishouBatchCreativePreviews) {
        List<KuaishouBatchGroupPreview> groups = new ArrayList<>();
        for (KuaishouBatchGroupPreview groupPreview : kuaishouBatchGroupPreviews) {
            List<KuaishouBatchCreativePreview> creatives = new ArrayList<>();
            for (KuaishouBatchCreativePreview creativePreview : kuaishouBatchCreativePreviews) {
                if (groupPreview.getPlanId().equals(creativePreview.getPlanId()) && creativePreview.getGroupId().equals(groupPreview.getId())) {
                    creatives.add(creativePreview);
                }
            }
            groupPreview.setKuaishouBatchCreativePreviews(creatives);
            groups.add(groupPreview);
        }
        List<KuaishouBatchCampaignPreview> campaigns = new ArrayList<>();
        for (KuaishouBatchCampaignPreview campaignPreview : campaignPreviewList) {
            List<KuaishouBatchGroupPreview> groupList = new ArrayList<>();
            for (KuaishouBatchGroupPreview group : groups) {
                if (campaignPreview.getId().equals(group.getPlanId())) {
                    groupList.add(group);
                }
            }
            campaignPreview.setKuaishouBatchGroupPreviews(groupList);
            campaigns.add(campaignPreview);
        }
        return campaigns;
    }

    /**
     * 根据预览数据创建广告计划
     *
     * @param
     * @return void
     * @throws
     * @author ZHAOXA
     */
    private void creativeCampaign(CtopOauthToken oauthToken, KuaishouBatchCampaignPreview campaign) throws Exception {
        KuaishouBatchCampaignPreview updateStatus = new KuaishouBatchCampaignPreview();
        updateStatus.setId(campaign.getId());
        Long campaignId = campaign.getCampaignId();
        if (Check.isNull(campaignId)) {
            JSONObject campaignJson = new JSONObject();
            campaignJson.put("campaign_name", campaign.getCampaignName());
            campaignJson.put("type", campaign.getCampaignType());
            if (!Check.isNull(campaign.getDayBudget())) {
                campaignJson.put("day_budget", campaign.getDayBudget());
            }
            if (!Check.isNull(campaign.getDayBudgetSchedule())) {
                campaignJson.put("day_budget_schedule", campaign.getDayBudgetSchedule());
            }
            Map<String, Object> campaignMap = kuaishouInterfaceService.campaignCreate(oauthToken.getAccessToken(), oauthToken.getAccountId(), campaignJson);
            Integer code = (Integer) campaignMap.get("code");
            if (code != 0) {
                updateStatus.setIsSuccess(0);
                updateStatus.setMessage((String) campaignMap.get("message"));
                campaignPreviewMapper.updateById(updateStatus);
                throw new Exception((String) campaignMap.get("message"));
            }
            campaignId = (Long) campaignMap.get("campaignId");
            /**
             *更新预览数据状态
             */
            updateStatus.setIsSuccess(1);
            updateStatus.setMessage((String) campaignMap.get("message"));
            updateStatus.setCampaignId(campaignId);
        } else {
            updateStatus.setIsSuccess(1);
            updateStatus.setMessage("执行成功");
        }
        campaignPreviewMapper.updateById(updateStatus);
        if (campaign.getPutStatus() == 2) {
            kuaiShouUpdateService.updateCampaignStatus(oauthToken.getAccessToken(), oauthToken.getAccountId(), updateStatus.getCampaignId(), campaign.getPutStatus(), "timingStart");
        }
        //创意广告组
        List<KuaishouBatchGroupPreview> groupPreviewList = campaign.getKuaishouBatchGroupPreviews();
        Long finalCampaignId = campaignId;
        groupPreviewList.forEach(group -> campaignService.submit(() -> {
            try {
                createCopyUnits(oauthToken, group, finalCampaignId);
            } catch (Exception e) {
                log.error("根据预览数据创建广告组异常", e);
            }
        }));
    }

    /**
     * 根据预览数据创建广告组
     * detail
     *
     * @param
     * @return void
     * @throws
     * @author ZHAOXA
     */
    private void createCopyUnits(CtopOauthToken token, KuaishouBatchGroupPreview groupPreview, Long campaignId) throws Exception {
        KuaishouBatchGroupPreview updateStatus = new KuaishouBatchGroupPreview();
        try {
            updateStatus.setId(groupPreview.getId());
            updateStatus.setCampaignId(campaignId);
            JSONObject unitJson = new JSONObject();
            unitJson.put("campaign_id", campaignId);
            // 资源位置
            String sceneId = groupPreview.getSceneId();
            JSONArray scene_id = JSONObject.parseArray(sceneId);
            unitJson.put("scene_id", scene_id);
            // 资源创作方式
            unitJson.put("unit_type", groupPreview.getUnitType());
            // 转化目标id
            if (!Check.isNull(groupPreview.getConvertId())) {
                unitJson.put("convert_id", groupPreview.getConvertId());
            }
            // 优先从系统应用商店下载
            if (!Check.isNull(groupPreview.getUseAppMarket())) {
                unitJson.put("use_app_market", groupPreview.getUseAppMarket());
            }
            // 应用商店列表
            if (!Check.isNull(groupPreview.getAppStore())) {
                unitJson.put("app_store", JSONObject.parseArray(groupPreview.getAppStore()));
            }
            //投放开始时间
            String beginTime = groupPreview.getBeginTime();
            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 = groupPreview.getEndTime();
            if (!Check.isNull(endTime)) {
                unitJson.put("end_time", endTime);
            }
            // 投放时间段
            String scheduleTime = groupPreview.getScheduleTime();
            if (!Check.isNull(scheduleTime)) {
                unitJson.put("schedule_time", scheduleTime);
            }
            // 广告组单日预算
            Integer dayBudget = groupPreview.getDayBudget();
            if (!Check.isNull(dayBudget)) {
                unitJson.put("day_budget", dayBudget);
            }
            // url类型
            if (!Check.isNull(groupPreview.getUrlType())) {
                unitJson.put("url_type", groupPreview.getUrlType());
            }
            // url
            if (!Check.isNull(groupPreview.getUrl())) {
                unitJson.put("url", groupPreview.getUrl());
            }
            // appId
            if (!Check.isNull(groupPreview.getAppId())) {
                unitJson.put("app_id", groupPreview.getAppId());
            }
            // 创意展现方式
            if (!Check.isNull(groupPreview.getShowMode())) {
                unitJson.put("show_mode", groupPreview.getShowMode());
            }
            //投放方式
            Integer speed = groupPreview.getSpeed();
            if (!Check.isNull(speed)) {
                unitJson.put("speed", speed);
            }
            Integer firstSceneId = valueOf(scene_id.get(0).toString());
            Long templateId = groupPreview.getTemplateId();
            if (!Check.isNull(templateId)) {
                if (firstSceneId != 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);
                    }
                }
            }
            // 出价
            Integer bid = groupPreview.getBid();
            if (!Check.isNull(bid)) {
                unitJson.put("bid", bid);
            }
            // 出价类型
            Integer bidType = groupPreview.getBidType();
            if (!Check.isNull(bidType)) {
                unitJson.put("bid_type", bidType);
            }
            // 深度转化出价
            Integer cpaBid = groupPreview.getCpaBid();
            if (!Check.isNull(cpaBid)) {
                unitJson.put("cpa_bid", cpaBid);
            }
            // 深度转化目标出价
            Integer deepConversionBid = groupPreview.getDeepConversionBid();
            if (!Check.isNull(deepConversionBid)) {
                unitJson.put("deep_conversion_bid", deepConversionBid);
            }
            // 深度转化目标
            Integer deepConversionType = groupPreview.getDeepConversionType();
            if (!Check.isNull(deepConversionType)) {
                unitJson.put("deep_conversion_type", deepConversionType);
            }
            // 优化目标
            Integer ocpxActionType = groupPreview.getOcpxActionType();
            if (!Check.isNull(ocpxActionType)) {
                unitJson.put("ocpx_action_type", ocpxActionType);
            }
            // 广告组的投放状态
            Integer putStatus = groupPreview.getPutStatus();
            if (!Check.isNull(putStatus)) {
                unitJson.put("put_status", putStatus);
            }
            //快手广告组名
            String unitName = groupPreview.getUnitName();
            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");
                    updateStatus.setIsSuccess(1);
                    updateStatus.setMessage((String) returnUnitMap.get("message"));
                    updateStatus.setUnitId(unitId);
                    createCopyCreatives(token, groupPreview.getKuaishouBatchCreativePreviews(), unitId, campaignId);
                } else {
                    updateStatus.setIsSuccess(0);
                    updateStatus.setMessage((String) returnUnitMap.get("message"));
                }
            } else {
                updateStatus.setIsSuccess(0);
                updateStatus.setMessage((String) "返回map数据为空！");
            }
        } catch (Exception e) {
            updateStatus.setIsSuccess(0);
            updateStatus.setMessage("创建组过程中调用快手接口异常");
            log.error("调用快手接口异常", e);
        }
        groupPreviewMapper.updateById(updateStatus);
    }

    /**
     * 执行多线程创建创意
     *
     * @param
     * @return void
     * @throws
     * @author ZHAOXA
     */
    private void createCopyCreatives(CtopOauthToken token, List<KuaishouBatchCreativePreview> creativePreviewList, Long unitId, Long campaignId) {
        creativePreviewList.forEach(creative -> campaignService.submit(() -> {
            try {
                createCreative(token, campaignId, unitId, creative);
            } catch (Exception e) {
                log.error("根据预览数据创建广告创意异常", e);
            }
        }));
    }

    /**
     * 根据预览数据创建广告创意
     *
     * @param oauthToken
     * @param unit_id
     * @param creative_list
     */
    private void createCreative(CtopOauthToken oauthToken, Long campaignId, Long unitId, KuaishouBatchCreativePreview creativePreview) throws Exception {
        KuaishouBatchCreativePreview updateStatus = new KuaishouBatchCreativePreview();
        updateStatus.setId(creativePreview.getId());
        updateStatus.setCampaignId(campaignId);
        updateStatus.setUnitId(unitId);
        try {
            JSONObject createJson = new JSONObject();
            createJson.put("advertiser_id", oauthToken.getAccountId());
            createJson.put("unit_id", unitId);
            createJson.put("creative_name", creativePreview.getCreativeName()); // 创意名称
            if (!Check.isNull(creativePreview.getPhotoId())) {
                createJson.put("photo_id", creativePreview.getPhotoId());  // 视频ID
            }
            KuaiShouVideoGet video = videoGetService.getVideoByPhotoId(Long.valueOf(creativePreview.getPhotoId()));
            if (!Check.isNull(video)) {
                createJson.put("creative_material_type", video.getMaterialType());  // 素材类型
            }
            if (!Check.isNull(creativePreview.getActionBarText())) {
                createJson.put("action_bar_text", creativePreview.getActionBarText());  // 行动号召按钮文案
            }
            if (!Check.isNull(creativePreview.getDescription())) {
                createJson.put("description", creativePreview.getDescription());  // 广告语
            }
            if (!Check.isNull(creativePreview.getStickerTitle())) {
                createJson.put("sticker_title", creativePreview.getStickerTitle());  // 封面广告语标题
            }
            if (!Check.isNull(creativePreview.getOverlayType())) {
                createJson.put("overlay_type", creativePreview.getOverlayType());  // 贴纸样式类型
            }
                /*if (!Check.isNull(creativePreview.getCreativeTag())) {
                    createJson.put("expose_tag", JSONObject.parseArray(creativePreview.getCreativeTag()));  // 广告标签
                }
                if (!Check.isNull(creativePreview.getJSONArray("new_expose_tag"))) {
                    createJson.put("new_expose_tag", creativePreview.getJSONArray("new_expose_tag"));  // 广告标签2期
                }*/
            if (!Check.isNull(creativePreview.getSiteId())) {
                createJson.put("site_id", creativePreview.getSiteId());  // 安卓下载中间页ID
            }
            if (!Check.isNull(creativePreview.getClickTrackUrl())) {
                createJson.put("click_track_url", creativePreview.getClickTrackUrl());  // 第三方点击检测链接
            }
            if (!Check.isNull(creativePreview.getImpressionUrl())) {
                createJson.put("impression_url", creativePreview.getImpressionUrl());  // 第三方开始播放监测链接
            }
            if (!Check.isNull(creativePreview.getAdPhotoPlayedT3sUrl())) {
                createJson.put("ad_photo_played_t3s_url", creativePreview.getAdPhotoPlayedT3sUrl());  // 第三方有效播放监测链接
            }
            if (!Check.isNull(creativePreview.getActionbarClickUrl())) {
                createJson.put("actionbar_click_url", creativePreview.getActionbarClickUrl());  // 第三方点击按钮监测链接
            }
            if (!Check.isNull(creativePreview.getCreativeCategory())) {
                createJson.put("creative_category", creativePreview.getCreativeCategory());  // 创意分类
            }
            if (!Check.isNull(creativePreview.getCreativeTag())) {
                createJson.put("creative_tag", JSONObject.parseArray(creativePreview.getCreativeTag()));  // 创意标签
            }
            String image_md5 = creativePreview.getImageSignature();
            String imageToken = null;
            if (!Check.isNull(image_md5)) {
                imageToken = getImageToken(image_md5, oauthToken.getAccountId(), oauthToken.getAccessToken());
            }
            if (!Check.isNull(imageToken)) {
                createJson.put("image_token", imageToken); // 自定义创意封面token
            }
            Map<String, Object> creativeMap = kuaishouInterfaceService.creativeCreate(oauthToken.getAccessToken(), oauthToken.getAccountId(), createJson, 1);
            JSONObject returnJson = new JSONObject();
            Integer code = (Integer) creativeMap.get("code");
            if (code == 0) {
                Long creativeId = (Long) creativeMap.get("creativeId");
                updateStatus.setIsSuccess(1);
                updateStatus.setMessage((String) creativeMap.get("message"));
                updateStatus.setCreativeId(creativeId);
            } else {
                updateStatus.setIsSuccess(0);
                updateStatus.setMessage((String) creativeMap.get("message"));
            }
        } catch (Exception e) {
            log.error("创建广告创意过程中调用快手接口异常", e);
            updateStatus.setIsSuccess(0);
            updateStatus.setMessage("创建广告创意过程中调用快手接口异常");
        }
        creativePreviewMapper.updateById(updateStatus);
    }

    /**
     * 根据封面MD5 获取imageToken
     *
     * @param md5
     * @param accountId
     * @param accessToken
     * @return
     */
    private String getImageToken(String md5, Long accountId, String accessToken) {
        String imageToken = null;
        QueryWrapper<KuaiShouImageGet> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account_id", accountId);
        queryWrapper.eq("signature", md5);
        queryWrapper.last("limit 1");
        KuaiShouImageGet imageGet = imageGetService.getOne(queryWrapper);
        if (!Check.isNull(imageGet)) {
            imageToken = imageGet.getImageToken();
        } else {
            MaterialCutFrame cutFrame = cutFrameService.selectByMd5(md5);
            if (!Check.isNull(cutFrame)) {
                imageToken = uploadService.kuauiShouImageUpload(cutFrame.getUrl(), md5, accountId, accessToken);
            }
        }
        return imageToken;
    }
}
