package org.jeecg.modules.ctop.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 com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.ctop.entity.MaterialUploadTask;
import org.jeecg.modules.ctop.mapper.MaterialUploadTaskMapper;
import org.jeecg.modules.ctop.service.IMaterialUploadTaskService;
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;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 同步素材任务
 *
 * @author jeecg-boot
 * 2021-10-21
 * @version V1.0
 */
@Service
@Slf4j
public class MaterialUploadTaskServiceImpl extends ServiceImpl<MaterialUploadTaskMapper, MaterialUploadTask> implements IMaterialUploadTaskService {

    @Autowired
    private MaterialUploadTaskMapper materialUploadTaskMapper;
    private static ExecutorService submitExecutorService = Executors.newFixedThreadPool(5);
    @Autowired
    private ICtopOauthTokenService tokenService;

    /**
     * 同步素材提交任务
     *
     * @param json
     * @return
     */

    @Override
    public JSONObject submitTask(JSONObject json) {
        JSONObject returnJson = new JSONObject();
        try {
            if (Check.isNull(json)) {
                throw new Exception("入参不能为空");
            }
            Integer mediaId = json.getInteger("mediaId");
            if (Check.isNull(mediaId)) {
                throw new Exception("媒体信息必传");
            }
            JSONArray materialArray = json.getJSONArray("materialArray");
            if (Check.isNull(materialArray)) {
                throw new Exception("请传入素材信息");
            }
            JSONArray accountArray = json.getJSONArray("accountArray");
            if (Check.isNull(accountArray)) {
                throw new Exception("请传入账户信息");
            }
            String loginId = json.getString("loginId");
            if (Check.isNull(loginId)) {
                throw new Exception("请传入登录人id");
            }
            String userName = json.getString("userName");
            if (Check.isNull(userName)) {
                throw new Exception("请传入登录人姓名");
            }
            Integer isMultiagent = json.getInteger("isMultiagent");
            if (Check.isNull(isMultiagent)) {
                throw new Exception("请传入主体信息");
            }
            Map<String, JSONObject> useMap = new HashMap<>();
            List<MaterialUploadTask> tasksList = new ArrayList<>();
            Integer shieldBackwardSwitch = null;
            // 快手任务提交
            if (mediaId == 2 || mediaId == 4) {
                for (int j = 0; j < materialArray.size(); j++) {
                    String materialId = materialArray.getString(j);
                    JSONObject materialInfo = materialUploadTaskMapper.getMaterialNameBySignature(materialId);
                    if (Check.isNull(materialInfo)) {
                        continue;
                    }
                    String materialName = materialInfo.getString("materialName");
                    String materialUrl = materialInfo.getString("materialUrl");
                    String signature = materialInfo.getString("signature");
                    for (int i = 0; i < accountArray.size(); i++) {
                        Long accountId = null;
                        Long userId = null;
                        if (mediaId == 2 || mediaId == 4) {
                            JSONObject accountJson = accountArray.getJSONObject(i);
                            if (Check.isNull(accountJson)) {
                                continue;
                            }
                            userId = accountJson.getLong("userId");
                            accountId = accountJson.getLong("accountId");
                            if (isMultiagent == 1) {
                                Integer count = materialUploadTaskMapper.getCountByUserIdAndMd5(userId, signature);
                                if (count > 0) {
                                    getUseMap(useMap, userId, materialName, signature);
                                    continue;
                                }
                            } else if (isMultiagent == 2) {
                                Integer count = materialUploadTaskMapper.getCountByaccountIdAndMd5(userId, accountId, signature);
                                if (count > 0) {
                                    getUseMap(useMap, userId, materialName, signature);
                                    continue;
                                }
                            }

                            shieldBackwardSwitch = json.getInteger("shieldBackwardSwitch");
                        }
                        MaterialUploadTask task = new MaterialUploadTask();
                        task.setAccountId(accountId);
                        if (!Check.isNull(userId)) {
                            task.setKuaishouUserId(userId);
                        }
                        task.setShieldBackwardSwitch(shieldBackwardSwitch);
                        task.setMediaId(mediaId);
                        task.setSignature(signature);
                        task.setUserId(loginId);
                        task.setUserName(userName);
                        task.setMaterialName(materialName);
                        task.setMaterialUrl(materialUrl);
                        task.setTaskStatus(0);
                        task.setRemarks("素材待同步");
                        tasksList.add(task);
                    }
                }
            } else if (mediaId == 1 || mediaId == 3) { // 头条任务提交
                for (int i = 0; i < materialArray.size(); i++) {
                    String id = materialArray.getString(i);
                    JSONObject materialInfo = materialUploadTaskMapper.getMaterialNameBySignature(id);
                    if (Check.isNull(materialInfo)) {
                        continue;
                    }
                    String materialName = materialInfo.getString("materialName");
                    String materialUrl = materialInfo.getString("materialUrl");
                    String signature = materialInfo.getString("signature");
                    Long accountId = accountArray.getLong(0);
                    Long projectId = materialUploadTaskMapper.getProjectIdByAccountId(accountId);
                    JSONObject videoJson = materialUploadTaskMapper.getVideoId(projectId, signature);
                    if (Check.isNull(videoJson)) { // 如果是校验为新素材  调用上传素材接口
                        MaterialUploadTask task = new MaterialUploadTask();
                        task.setShieldBackwardSwitch(shieldBackwardSwitch);
                        task.setMediaId(mediaId);
                        task.setSignature(signature);
                        task.setUserId(loginId);
                        task.setUserName(userName);
                        task.setMaterialName(materialName);
                        task.setMaterialUrl(materialUrl);
                        task.setTaskStatus(0);
                        task.setRemarks("素材待同步");
                        task.setAccountId(accountId);
                        task.setSyncAccounts(accountArray.toJSONString());
                        tasksList.add(task);
                    } else {
                        submitExecutorService.submit(new Runnable() {
                            @Override
                            public void run() {
                                if (!Check.isNull(accountArray)) {
                                    syncBytedance(videoJson.getLong("accountId"), mediaId, signature, accountArray, loginId, userName, materialName, materialUrl, videoJson.getString("videoId"));
                                }
                            }
                        });
                    }
                }
            }

            if (!Check.isNull(tasksList)) {
                materialUploadTaskMapper.replaceBatch(tasksList);
            }
            returnJson.put("code", 0);
            returnJson.put("message", "任务提交成功");
            if (!Check.isNullMap(useMap)) {
                JSONArray array = new JSONArray();
                for (Map.Entry<String, JSONObject> entry : useMap.entrySet()) {
                    JSONObject mapValue = entry.getValue();
                    array.add(mapValue);
                }
                returnJson.put("data", array);
            }
        } catch (Exception e) {
            returnJson.put("code", -1);
            returnJson.put("message", e.getMessage());
        }

        return returnJson;
    }

    private void syncBytedance(Long accountId, Integer mediaId, String signature, JSONArray accountArray, String loginId, String userName, String materialName, String materialUrl, String videoId) {
        log.info("开始素材推送,code:{},账户数:{}", signature, accountArray.size());
        CtopOauthToken token = tokenService.getTokenByAccountId(accountId);
        if (Check.isNull(token)) {
            return;
        }
        List<MaterialUploadTask> tasksList = new ArrayList<>();
        List<List<Object>> accountIds = Lists.partition(accountArray, 49);
        for (int i = 0; i < accountIds.size(); i++) {
            List<Object> objects = accountIds.get(i);
            JSONObject params = new JSONObject();
            params.put("advertiser_id", accountId);
            params.put("target_advertiser_ids", JSONArray.toJSONString(objects));
            JSONArray video_ids = new JSONArray();
            video_ids.add(videoId);
            params.put("video_ids", video_ids);
            JSONObject jsonObject = HttpUtils.bytedancePostRequest(token.getAccessToken(), "https://ad.oceanengine.com/open_api/2/file/material/bind/", params);
            Map<Long, String> dataMap = new HashMap<>();
            if (!Check.isNull(jsonObject)) {
                Integer code = jsonObject.getInteger("code");
                if (code == 0) {
                    log.info("素材推送成功,code:{},账户数:{}", signature, accountArray.size());
                    JSONObject data = jsonObject.getJSONObject("data");
                    if (!Check.isNull(data)) {
                        JSONArray fail_list = data.getJSONArray("fail_list");
                        if (!Check.isNull(fail_list)) {
                            for (int j = 0; j < fail_list.size(); j++) {
                                JSONObject failJson = fail_list.getJSONObject(j);
                                dataMap.put(failJson.getLong("target_advertiser_id"), failJson.getString("fail_reason"));
                            }
                        }
                    }
                } else {
                    log.info("素材推送失败,code:{},账户数:{},返回信息：{}", signature, accountArray.size(), jsonObject);
                }
                for (int j = 0; j < objects.size(); j++) {
                    Long target_advertiser_id = (Long) objects.get(j);
                    MaterialUploadTask task = new MaterialUploadTask();
                    task.setMediaId(mediaId);
                    task.setSignature(signature);
                    task.setUserId(loginId);
                    task.setUserName(userName);
                    task.setMaterialName(materialName);
                    task.setMaterialUrl(materialUrl);
                    if (code != 0) {
                        if (jsonObject.getString("message").contains("与原广告主不属于同一主体") || jsonObject.getString("message").contains("部分视频无权限或不存在")) {
                            task.setTaskStatus(0);
                            task.setRemarks("待重新提交");
                        } else {
                            task.setTaskStatus(4);
                            task.setRemarks(jsonObject.getString("message"));
                        }
                    } else {
                        if (!Check.isNull(dataMap)) {
                            String fail_reason = dataMap.get(target_advertiser_id);
                            if (Check.isNull(fail_reason)) {
                                task.setTaskStatus(3);
                                task.setRemarks("素材同步完成");
                            } else {
                                task.setTaskStatus(4);
                                task.setRemarks("此素材已存在广告主账户中");
                            }
                        }
                    }
                    task.setAccountId(target_advertiser_id);
                    tasksList.add(task);
                }
            }
        }
        materialUploadTaskMapper.replaceBatch(tasksList);
    }

    @Override
    public PageInfo<List<JSONObject>> uploadDetail(String signature, Integer pageNo, Integer pageSize) {
        PageHelper.startPage(pageNo, pageSize, false);
        List<JSONObject> details = materialUploadTaskMapper.uploadDetail(signature);
        Integer total = materialUploadTaskMapper.getCount(signature);
        PageInfo pageInfo = new PageInfo(details);
        pageInfo.setTotal(total);
        return pageInfo;
    }


    private Map<String, JSONObject> getUseMap(Map<String, JSONObject> userMap, Long userId, String materialName, String signature) {
        JSONObject useJson = userMap.get(signature);
        if (Check.isNull(useJson)) {
            JSONObject addJson = new JSONObject();
            addJson.put("materialName", materialName);
            addJson.put("message", "此素材正在同步中或已同步");
            JSONArray userIdArray = new JSONArray();
            userIdArray.add(userId);
            addJson.put("ids", userIdArray);
            userMap.put(signature, addJson);

        } else {
            JSONArray userIdArray = useJson.getJSONArray("ids");
            userIdArray.add(userId);
        }
        return userMap;
    }

}
