package cn.com.ctop.alarm.modules.service.impl;

import cn.com.ctop.alarm.modules.constant.MatchLogic;
import cn.com.ctop.alarm.modules.entity.AlarmEventSend;
import cn.com.ctop.alarm.modules.entity.RuleAccountTemplate;
import cn.com.ctop.alarm.modules.entity.RuleAccountThreshold;
import cn.com.ctop.alarm.modules.entity.RuleBase;
import cn.com.ctop.alarm.modules.entity.RuleGroup;
import cn.com.ctop.alarm.modules.entity.RuleIndicator;
import cn.com.ctop.alarm.modules.entity.RuleTemplate;
import cn.com.ctop.alarm.modules.mapper.AlarmEventSendMapper;
import cn.com.ctop.alarm.modules.mapper.RuleAccountTemplateMapper;
import cn.com.ctop.alarm.modules.mapper.RuleAccountThresholdMapper;
import cn.com.ctop.alarm.modules.mapper.RuleBaseMapper;
import cn.com.ctop.alarm.modules.mapper.RuleGroupMapper;
import cn.com.ctop.alarm.modules.mapper.RuleIndicatorMapper;
import cn.com.ctop.alarm.modules.mapper.RuleTemplateMapper;
import cn.com.ctop.alarm.modules.service.IRuleAccountTemplateService;
import cn.com.ctop.alarm.modules.service.IRuleGroupService;
import cn.com.ctop.common.module.entity.CtopOauthToken;
import cn.com.ctop.common.module.entity.UserAllocation;
import cn.com.ctop.common.module.mapper.SysUserMapper;
import cn.com.ctop.common.module.mapper.UserAllocationMapper;
import cn.com.ctop.common.module.service.ICtopOauthTokenService;
import cn.com.ctop.common.module.service.IRuleDataAccountService;
import cn.com.ctop.common.module.service.ISendMessageService;
import cn.com.ctop.common.module.utils.Check;
import cn.com.ctop.common.module.utils.SendMailUtil;
import cn.com.ctop.kuaishou.modules.batch.service.IKuaiShouUpdateService;
import cn.com.ctop.toutiao.modules.material.service.IByteDanceAdvertisePlanService;
import cn.com.ctop.toutiao.modules.material.service.IByteDanceCreativeService;
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.xxl.job.core.enums.NoEn;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.UUID;

/**
 * 规则组
 *
 * @author jeecg-boot
 * @version V1.0
 * @date 2020-11-15
 */
@Slf4j
@Service
public class RuleGroupServiceImpl extends ServiceImpl<RuleGroupMapper, RuleGroup> implements IRuleGroupService {

    @Autowired
    private RuleBaseMapper ruleBaseMapper;
    @Autowired
    private RuleGroupMapper ruleGroupMapper;
    @Autowired
    private RuleIndicatorMapper ruleIndicatorMapper;
    @Autowired
    private RuleAccountThresholdMapper ruleAccountThresholdMapper;
    @Autowired
    private RuleAccountTemplateMapper ruleAccountTemplateMapper;
    @Autowired
    private RuleTemplateMapper ruleTemplateMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private IRuleGroupService ruleGroupService;
    @Autowired
    private IRuleAccountTemplateService ruleAccountTemplateService;
    @Autowired
    private ISendMessageService sendMessageService;
    @Autowired
    private IKuaiShouUpdateService kuaiShouUpdateService;
    @Autowired
    private ICtopOauthTokenService oauthTokenService;
    @Autowired
    private IRuleDataAccountService ruleDataAccountService;
    @Autowired
    private AlarmEventSendMapper alarmEventSendMapper;
    @Autowired
    private UserAllocationMapper userAllocationMapper;
    @Autowired
    private IByteDanceAdvertisePlanService byteDanceAdvertisePlanService;
    @Autowired
    private IByteDanceCreativeService byteDanceCreativeService;
    @Autowired
    private ICtopOauthTokenService ctopOauthTokenService;

    private JSONObject userObj = null;
    private final static String ACCOUNT = "account";
    private final static String PLAN = "plan";
    private final static String CREATIVE = "creative";

    @Override
    public void checkRules() {
        log.info("------start------");
        Long startTime = System.currentTimeMillis();
        //查询账户绑定过的规则模板
        List<RuleAccountTemplate> ruleAccountTemplates = ruleAccountTemplateMapper.selectByMap(null);
        if (Check.isNull(ruleAccountTemplates)) {
            log.error("查询账户绑定过的规则模板失败");
            return;
        }
        //获取规则集
        Map<Long, Object> ruleGroupMap = getRuleGroupMap();
        if (Check.isNull(ruleGroupMap)) {
            log.error("获取规则集失败");
            return;
        }
        //获取指标内容
        JSONObject indicators = getRuleIndicator();
        if (Check.isNull(indicators)) {
            log.error("获取指标内容失败");
            return;
        }
        for (RuleAccountTemplate templates : ruleAccountTemplates) {
            matchAlarmRules(ruleGroupMap, indicators, templates);
        }
        Long endTime = System.currentTimeMillis();
        log.info("------end------共耗时: {} ms", endTime - startTime);
    }

    /**
     * 匹配预警规则
     *
     * @param ruleGroups 规则数据集
     * @param templates  规则模板
     * @param indicators 指标码
     * @return void
     * @throws
     * @author ZHAOXA
     */
    private void matchAlarmRules(Map<Long, Object> ruleGroupMap, JSONObject indicators, RuleAccountTemplate templates) {
        userObj = new JSONObject();
        //查询匹配数据
        JSONObject matchData = getRuleData(templates.getAccountId());
        if (Check.isNull(matchData)) {
            log.warn("查询匹配数据失败");
            return;
        }
        boolean isCopy = false;
        Map<Long, Object> map = (Map<Long, Object>) ruleGroupMap.get(templates.getTemplateId());
        //媒体类型 1：头条2：快手
        Integer type = (Integer) map.get("type");
        //常规规则+阈值
        List<RuleGroup> notCopyGroups = (List<RuleGroup>) map.get("notCopy");
        JSONObject notCopythreshold = getThreshold(templates.getAccountId(), isCopy);
        //可复制规则+阈值
        List<RuleGroup> isCopyGroups = (List<RuleGroup>) map.get("isCopy");
        JSONObject isCopythreshold = new JSONObject();
        if (!Check.isNull(isCopyGroups)) {
            isCopy = true;
            isCopythreshold = getThreshold(templates.getAccountId(), isCopy);
        }
        log.info("已获取账户（{}）的数据，开始匹配规则", templates.getAccountId());
        UserAllocation userAllocations = userAllocationMapper.getUserAllocation(templates.getAccountId());
        String accountName = "";
        if (!Check.isNull(userAllocations)) {
            accountName = userAllocations.getAuthName();
        }
        try {
            if (!Check.isNull(notCopyGroups) && !Check.isNull(notCopythreshold)) {
                checkRuleGroups(notCopyGroups, notCopythreshold, indicators, matchData, type, false, accountName);
            }
            if (isCopy && !Check.isNull(isCopythreshold)) {
                checkRuleGroups(isCopyGroups, isCopythreshold, indicators, matchData, type, isCopy, accountName);
            }

        } catch (Exception e) {
            log.error("匹配规则逻辑异常", e);
        }
    }

    /**
     * 组合规则匹配逻辑
     *
     * @param ruleGroups   规则组集
     * @param thresholdObj 阈值数据
     * @param indicators   指标数据
     * @param matchData    匹配数据
     * @param type         媒体类型 1：头条2：快手
     * @param isCopy       是否复制规则
     * @return void
     * @throws
     * @author ZHAOXA
     */
    private void checkRuleGroups(List<RuleGroup> ruleGroups, JSONObject thresholdObj, JSONObject indicators, JSONObject matchData, Integer type, boolean isCopy, String accountName) {
        for (RuleGroup ruleGroup : ruleGroups) {
            JSONArray complianceList = new JSONArray();
            List<RuleBase> ruleBaseList = ruleGroup.getRuleBaseList();
            if (Check.isNull(ruleBaseList)) {
                continue;
            }
            //复制逻辑
            if (isCopy) {
                JSONObject batchNo = thresholdObj.getJSONObject(ruleGroup.getId().toString());
                for (Map.Entry<String, Object> entry : batchNo.entrySet()) {
                    JSONObject thresholdJn = (JSONObject) entry.getValue();
                    if (!Check.isNull(thresholdJn)) {
                        CombinationRule(ruleBaseList, thresholdJn, indicators, matchData, complianceList);
                    }
                }
            } else {
                boolean isGroup = "group".equals(ruleGroup.getRuleType());
                //匹配组合规则
                if (isGroup) {
                    CombinationRule(ruleBaseList, thresholdObj, indicators, matchData, complianceList);
                    //匹配单规则
                } else {
                    RuleBase ruleBase = ruleBaseList.get(0);
                    if (Check.isNull(ruleBase)) {
                        continue;
                    }
                    //指标对象
                    JSONObject indicator = indicators.getJSONObject(ruleBase.getIndicatorCode());
                    //指标阈值
                    String threshold = thresholdObj.getString(ruleBase.getId().toString());
                    //阈值为空时，或者阈值为“unlimited”（不限），不执行该规则
                    if (Check.isNull(threshold) || threshold.contains("unlimited")) {
                        continue;
                    }
                    //维度数据
                    JSONArray dimensionData = matchData.getJSONArray(ruleBase.getRuleDimension());
                    if (!Check.isNull(dimensionData)) {
                        for (int i = 0; i < dimensionData.size(); i++) {
                            JSONObject obj = dimensionData.getJSONObject(i);
                            String value = obj.getString(ruleBase.getIndicatorCode());
                            if (MatchLogic.matchCondition(indicator, ruleBase.getRuleCondition(), threshold, value, obj)) {
                                complianceList.add(obj);
                            }
                        }
                    }
                }
            }
            if (!Check.isNull(complianceList)) {
                getAndSendMessag(complianceList, ruleGroup, accountName);
            }
        }
    }

    /**
     * 组合规则匹配逻辑
     *
     * @param ruleGroup    规则组对象
     * @param ruleBaseList 单条规则数据集
     * @param thresholdObj 阈值数据
     * @param indicators   指标数据
     * @param matchData    匹配数据
     * @param type         媒体类型 1：头条2：快手
     * @param accountName  账户名称
     * @return void
     * @throws
     * @author ZHAOXA
     */
    private void CombinationRule(List<RuleBase> ruleBaseList, JSONObject thresholdObj, JSONObject indicators, JSONObject matchData, JSONArray complianceList) {
        //符合规则的数据集
        JSONArray targetDatas = new JSONArray();
        JSONArray planDatas = new JSONArray();
        JSONArray creativeDatas = new JSONArray();
        JSONArray accountDatas = new JSONArray();
        for (RuleBase ruleBase : ruleBaseList) {
            //指标对象
            JSONObject indicator = indicators.getJSONObject(ruleBase.getIndicatorCode());
            //指标阈值
            String threshold = thresholdObj.getString(ruleBase.getId().toString());
            //阈值为空时，或者阈值为“unlimited”（不限），不执行该规则
            if (Check.isNull(threshold) || "unlimited".equals(threshold)) {
                if (!Check.isNull(accountDatas)) {
                    accountDatas = null;
                }
                if (!Check.isNull(planDatas)) {
                    planDatas = null;
                }
                if (!Check.isNull(creativeDatas)) {
                    creativeDatas = null;
                }
                if (!Check.isNull(targetDatas)) {
                    targetDatas = null;
                }
                break;
            }
            JSONArray dimensionData = matchData.getJSONArray(ruleBase.getRuleDimension());
            if (Check.isNull(dimensionData)) {
                if (!Check.isNull(accountDatas)) {
                    accountDatas = null;
                }
                if (!Check.isNull(planDatas)) {
                    planDatas = null;
                }
                if (!Check.isNull(creativeDatas)) {
                    creativeDatas = null;
                }
                if (!Check.isNull(targetDatas)) {
                    targetDatas = null;
                }
                break;
            }
            //账户维度数据
            if (ACCOUNT.equals(ruleBase.getRuleDimension())) {
                JSONObject accountEntity = dimensionData.getJSONObject(0);
                if (MatchLogic.matchCondition(indicator, ruleBase.getRuleCondition(), threshold, accountEntity.getString(ruleBase.getIndicatorCode()), accountEntity)) {
                    if (Check.isNull(accountDatas)) {
                        accountDatas.add(accountEntity);
                    }
                } else {
                    if (!Check.isNull(accountDatas)) {
                        accountDatas = null;
                    }
                    if (!Check.isNull(planDatas)) {
                        planDatas = null;
                    }
                    if (!Check.isNull(creativeDatas)) {
                        creativeDatas = null;
                    }
                    if (!Check.isNull(targetDatas)) {
                        targetDatas = null;
                    }
                    break;
                }
            } else if (PLAN.equals(ruleBase.getRuleDimension())) {
                planDatas = getOKData(planDatas, dimensionData, ruleBase, indicator, threshold);
                if (Check.isNull(planDatas)) {
                    if (!Check.isNull(accountDatas)) {
                        accountDatas = null;
                    }
                    if (!Check.isNull(planDatas)) {
                        planDatas = null;
                    }
                    if (!Check.isNull(creativeDatas)) {
                        creativeDatas = null;
                    }
                    if (!Check.isNull(targetDatas)) {
                        targetDatas = null;
                    }
                    break;
                }
            } else if (CREATIVE.equals(ruleBase.getRuleDimension())) {
                creativeDatas = getOKData(creativeDatas, dimensionData, ruleBase, indicator, threshold);
                if (Check.isNull(creativeDatas)) {
                    if (!Check.isNull(accountDatas)) {
                        accountDatas = null;
                    }
                    if (!Check.isNull(planDatas)) {
                        planDatas = null;
                    }
                    if (!Check.isNull(creativeDatas)) {
                        creativeDatas = null;
                    }
                    if (!Check.isNull(targetDatas)) {
                        targetDatas = null;
                    }
                    break;
                }
            } else if ("target".equals(ruleBase.getRuleDimension())) {
                targetDatas = getOKData(targetDatas, dimensionData, ruleBase, indicator, threshold);
                if (Check.isNull(targetDatas)) {
                    if (!Check.isNull(accountDatas)) {
                        accountDatas = null;
                    }
                    if (!Check.isNull(planDatas)) {
                        planDatas = null;
                    }
                    if (!Check.isNull(creativeDatas)) {
                        creativeDatas = null;
                    }
                    if (!Check.isNull(targetDatas)) {
                        targetDatas = null;
                    }
                    break;
                }
            }
        }
        //获取达标可发送的数据
        JSONArray sendData = MatchLogic.getSendData(accountDatas, planDatas, creativeDatas, targetDatas);
        if (!Check.isNull(sendData)) {
            complianceList.addAll(sendData);
        }
    }

    /**
     * @param ruleDatas     达标数据集
     * @param dimensionData 匹配数据
     * @param ruleBase      规则
     * @param type          数据类型
     * @param threshold     阈值
     * @return void
     * @throws
     * @author ZHAOXA
     */
    private JSONArray getOKData(JSONArray ruleDatas, JSONArray dimensionData, RuleBase ruleBase, JSONObject indicator, String threshold) {
        if (!Check.isNull(ruleDatas)) {
            JSONArray okData = new JSONArray();
            for (int i = 0; i < ruleDatas.size(); i++) {
                JSONObject targetEntity = ruleDatas.getJSONObject(i);
                String value = targetEntity.getString(ruleBase.getIndicatorCode());
                if (MatchLogic.matchCondition(indicator, ruleBase.getRuleCondition(), threshold, value, targetEntity)) {
                    okData.add(targetEntity);
                }
            }
            return okData;
        }
        for (int i = 0; i < dimensionData.size(); i++) {
            JSONObject targetEntity = dimensionData.getJSONObject(i);
            String value = targetEntity.getString(ruleBase.getIndicatorCode());
            if (MatchLogic.matchCondition(indicator, ruleBase.getRuleCondition(), threshold, value, targetEntity)) {
                ruleDatas.add(targetEntity);
            }
        }
        return ruleDatas;
    }

    private void getAndSendMessag(JSONArray complianceList, RuleGroup ruleGroup, String accountName) {
        Long accountId = complianceList.getJSONObject(0).getLong("accountId");
        if (Check.isNull(accountId)) {
            return;
        }
        JSONObject user = getUserByAccountId(accountId);
        StringJoiner creativeJoiner = new StringJoiner("，");
        StringJoiner planJoiner = new StringJoiner("，");
        StringJoiner isNullCreativeJoiner = new StringJoiner("，");
        StringJoiner isNullPlanJoiner = new StringJoiner("，");
        for (int i = 0; i < complianceList.size(); i++) {
            JSONObject obj = complianceList.getJSONObject(i);
            boolean isNull = obj.getBoolean("isNull");
            if (isNull) {
                if (!Check.isNull(obj.getString("creativeId"))) {
                    //字节小于1800时
                    if (isNullCreativeJoiner.toString().getBytes().length <= 1800) {
                        isNullCreativeJoiner.add(obj.getString("creativeId"));
                    } else {
                        String message = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, CREATIVE, isNullCreativeJoiner.toString(), isNull);
                        sendMsg(message, ruleGroup, user, CREATIVE, isNullCreativeJoiner.toString(), accountId);
                        isNullCreativeJoiner = new StringJoiner("，");
                        isNullCreativeJoiner.add(obj.getString("creativeId"));
                    }
                } else if (!Check.isNull(obj.getLong("planId"))) {
                    if (isNullPlanJoiner.toString().getBytes().length <= 1800) {
                        isNullPlanJoiner.add(obj.getString("planId"));
                    } else {
                        String msg = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, PLAN, isNullPlanJoiner.toString(), isNull);
                        sendMsg(msg, ruleGroup, user, PLAN, isNullPlanJoiner.toString(), accountId);
                        isNullPlanJoiner = new StringJoiner("，");
                        isNullPlanJoiner.add(obj.getString("planId"));
                    }
                } else {
                    String msg = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, null, null, isNull);
                    sendMsg(msg, ruleGroup, user, ACCOUNT, null, accountId);
                }
            } else {
                if (!Check.isNull(obj.getString("creativeId"))) {
                    //字节小于1800时（消息支持最大2048字节）
                    if (creativeJoiner.toString().getBytes().length <= 1800) {
                        creativeJoiner.add(obj.getString("creativeId"));
                    } else {
                        String message = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, CREATIVE, creativeJoiner.toString(), isNull);
                        sendMsg(message, ruleGroup, user, CREATIVE, creativeJoiner.toString(), accountId);
                        creativeJoiner = new StringJoiner("，");
                        creativeJoiner.add(obj.getString("creativeId"));
                    }
                } else if (!Check.isNull(obj.getLong("planId"))) {
                    if (planJoiner.toString().getBytes().length <= 1800) {
                        planJoiner.add(obj.getString("planId"));
                    } else {
                        String msg = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, PLAN, planJoiner.toString(), isNull);
                        sendMsg(msg, ruleGroup, user, PLAN, planJoiner.toString(), accountId);
                        planJoiner = new StringJoiner("，");
                        planJoiner.add(obj.getString("planId"));
                    }
                } else {
                    String msg = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, null, null, isNull);
                    sendMsg(msg, ruleGroup, user, ACCOUNT, null, accountId);
                }
            }
        }
        if (!Check.isNull(creativeJoiner.toString())) {
            String creativeMsg = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, CREATIVE, creativeJoiner.toString(), false);
            sendMsg(creativeMsg, ruleGroup, user, CREATIVE, creativeJoiner.toString(), accountId);
        }
        if (!Check.isNull(planJoiner.toString())) {
            String planMsg = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, PLAN, planJoiner.toString(), false);
            sendMsg(planMsg, ruleGroup, user, PLAN, planJoiner.toString(), accountId);
        }
        if (!Check.isNull(isNullCreativeJoiner.toString())) {
            String isNullCreativeMsg = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, CREATIVE, isNullCreativeJoiner.toString(), true);
            sendMsg(isNullCreativeMsg, ruleGroup, user, CREATIVE, isNullCreativeJoiner.toString(), accountId);
        }
        if (!Check.isNull(isNullPlanJoiner.toString())) {
            String isNullPlanMsg = MatchLogic.getMessage(ruleGroup.getGroupName(), accountId, accountName, PLAN, isNullPlanJoiner.toString(), true);
            sendMsg(isNullPlanMsg, ruleGroup, user, PLAN, isNullPlanJoiner.toString(), accountId);
        }
    }

    /**
     * 发送消息
     *
     * @param ruleGroup 达标的规则组对象
     * @param obj       达标数据对象
     * @param type      1：头条2：快手
     * @param isNull    查询的值为空
     * @return void
     * @throws
     * @author ZHAOXA
     */
    private void sendMsg(String msg, RuleGroup ruleGroup, JSONObject user, String type, String ids, Long accountId) {
        try {
            boolean isPause = "PAUSE".equals(ruleGroup.getOperate());
            if (isPause) {
                //type 1：头条2：快手
                if (NoEn.NO1.valueStr().equals(type)) {
                    isPause = touTiaoshutDown(accountId, ids, type);
                } else {
                    msg = kuaiShoushutDown(accountId, ids, type, user.getString("id"), msg);
                    if (msg.getBytes().length >= 2048) {
                        msg = msg.replace("，", ",");
                    }
                }
            }
            if (isPause) {
                msg += "现已被关停，请您及时查看并调整！";
            } else {
                msg += "请您及时查看并调整！";
            }
            String sendType = ruleGroup.getSendType();
            if ("SMS".equals(sendType)) {

            } else if ("EMAIL".equals(sendType)) {
                List<String> mailList = new ArrayList<>();
                mailList.add(user.getString("email"));
                SendMailUtil.sendMail(mailList, ruleGroup.getGroupName() + "预警", msg);
            } else if ("TEL".equals(sendType)) {

            } else {
//                sendMessageService.sendMessage("1b3deb8258e84df994f1371a51cfc14a", msg);
                sendMessageService.sendMessage(user.getString("id"), msg);
                Thread.sleep(200);
            }
            if (!Check.isNull(msg)) {
                AlarmEventSend send = new AlarmEventSend();
                send.setUserId(user.getString("id"));
                send.setAlarmDetail(msg.replace("<br/>", "，"));
                send.setAlarmStatus(NoEn.NO1.valueStr());
                send.setGroupId(ruleGroup.getId());
                send.setGroupName(ruleGroup.getGroupName());
                if (CREATIVE.equals(type)) {
                    send.setRuleDimension(CREATIVE);
                } else if (PLAN.equals(type)) {
                    send.setRuleDimension(PLAN);
                } else {
                    send.setRuleDimension(ACCOUNT);
                }
                send.setCreateTime(new Date());
                alarmEventSendMapper.insert(send);
            }
        } catch (Exception e) {
            log.error("发送消息异常", e);
        }
    }

    /**
     * 根据accountId获取人员对象
     *
     * @param accountId 账户ID
     * @return com.alibaba.fastjson.JSONObject
     * @throws
     * @author ZHAOXA
     */
    private JSONObject getUserByAccountId(Long accountId) {
        JSONObject obj = userObj.getJSONObject(accountId.toString());
        if (Check.isNull(obj)) {
            JSONObject user = sysUserMapper.selectUserByAccount(accountId);
            userObj.put(accountId.toString(), user);
            return user;
        }
        return obj;
    }

    /**
     * 关停操作
     *
     * @param
     * @return boolean
     * @throws
     * @author ZHAOXA
     */
    private String kuaiShoushutDown(Long accountId, String ids, String type, String userId, String msg) {
        CtopOauthToken token = oauthTokenService.getTokenByAccountId(accountId);
        Map<String, Object> updateMap = new HashMap<>();
        if (!Check.isNull(token) && !Check.isNull(ids)) {
            String[] idSplit = ids.split("，");
            for (String id : idSplit) {
                if (CREATIVE.equals(type)) {
                    updateMap = kuaiShouUpdateService.updateCreativeStatus(token.getAccessToken(), accountId, Long.valueOf(id), NoEn.NO2.valueInt(), userId);
                    if (!(boolean) updateMap.get("success")) {
                        msg = msg.replace(id, id + "(F)");
                    }
                } else {
                    updateMap = kuaiShouUpdateService.updateCampaignStatus(token.getAccessToken(), accountId, Long.valueOf(id), NoEn.NO2.valueInt(), userId);
                    if (!(boolean) updateMap.get("success")) {
                        msg = msg.replace(id, id + "(F)");
                    }
                }
            }
        }
        return msg;
    }

    /**
     * 头条关停
     *
     * @param
     * @return boolean
     * @throws
     * @author ZHAOXA
     */
    private boolean touTiaoshutDown(Long accountId, String ids, String type) {
        Boolean flag = false;
        try {
            Map<String, Object> result = new HashMap<>();
            if (!Check.isNull(ids)) {
                String[] split = ids.split("，");
                JSONArray planId = new JSONArray();
                //最大更新100条数据，做拆分
                if (split.length > 100) {
                    JSONArray planId2 = new JSONArray();
                    StringJoiner str = new StringJoiner(",");
                    StringJoiner str2 = new StringJoiner(",");
                    for (int i = 0; i < split.length; i++) {
                        if (i > 99) {
                            str2.add(split[i]);
                            planId2.add(split[i]);
                        } else {
                            str.add(split[i]);
                            planId.add(split[i]);
                        }
                    }
                    if (PLAN.equals(type)) {
                        CtopOauthToken token = ctopOauthTokenService.getTokenByAccountId(accountId);
                        result = byteDanceAdvertisePlanService.updateAdvertiserPlanStatus(token, planId, "AD_STATUS_DISABLE");
                        if (planId2.size() > 0) {
                            result = byteDanceAdvertisePlanService.updateAdvertiserPlanStatus(token, planId2, "AD_STATUS_DISABLE");
                        }
                    } else {
                        result = byteDanceCreativeService.advertiserCreativeUpdateStatus(accountId, str.toString(), "disable");
                        if (str2.length() > 0) {
                            result = byteDanceCreativeService.advertiserCreativeUpdateStatus(accountId, str2.toString(), "disable");
                        }
                    }
                    //低于100条数据，直接执行
                } else {
                    if (PLAN.equals(type)) {
                        for (String id : split) {
                            planId.add(id);
                        }
                        CtopOauthToken token = ctopOauthTokenService.getTokenByAccountId(accountId);
                        result = byteDanceAdvertisePlanService.updateAdvertiserPlanStatus(token, planId, "AD_STATUS_DISABLE");
                    } else {
                        result = byteDanceCreativeService.advertiserCreativeUpdateStatus(accountId, ids.replace("，", ","), "disable");
                    }
                }
                flag = !Check.isNull(result.get("code")) && (int) result.get("code") == 0;
            }
        } catch (Exception e) {
            log.error("头条账户：{}，关停{}失败", accountId, type, e);
        }
        return flag;
    }


    //整理阈值数据
    public JSONObject getThreshold(Long accountId, boolean isCopy) {
        JSONObject obj = new JSONObject();
        try {
            if (isCopy) {
                List<Long> groupList = ruleAccountThresholdMapper.selectGroupIdsByAccountId(accountId);
                if (Check.isNull(groupList)) {
                    return null;
                }
                for (Long groupId : groupList) {
                    JSONObject groupIdObj = new JSONObject();
                    List<String> batchNos = ruleAccountThresholdMapper.selectbatchNosByGroupIdId(accountId, groupId);
                    if (Check.isNull(batchNos)) {
                        return null;
                    }
                    for (String batchNo : batchNos) {
                        JSONObject batchNoObj = new JSONObject();
                        List<RuleAccountThreshold> thresholdList = ruleAccountThresholdMapper.selectCopyThresholdByAccountId(accountId, groupId, batchNo);
                        if (Check.isNull(thresholdList)) {
                            return null;
                        }
                        for (RuleAccountThreshold threshold : thresholdList) {
                            batchNoObj.put(String.valueOf(threshold.getRuleId()), threshold.getThreshold());
                        }
                        groupIdObj.put(batchNo.toString(), batchNoObj);
                    }
                    obj.put(groupId.toString(), groupIdObj);
                }
            } else {
                List<RuleAccountThreshold> thresholdList = ruleAccountThresholdMapper.selectByAccountId(accountId);
                if (Check.isNull(thresholdList)) {
                    return null;
                }
                for (RuleAccountThreshold threshold : thresholdList) {
                    obj.put(String.valueOf(threshold.getRuleId()), threshold.getThreshold());
                }
            }
        } catch (Exception e) {
            log.error("获取账户阈值数据集失败", e);
        }
        return obj;

    }

    //整理指标数据
    public JSONObject getRuleIndicator() {
        JSONObject obj = new JSONObject();
        try {
            List<RuleIndicator> indicators = ruleIndicatorMapper.selectByMap(null);
            if (Check.isNull(indicators)) {
                return null;
            }
            for (RuleIndicator indicator : indicators) {
                obj.put(indicator.getCode(), indicator);
            }
        } catch (Exception e) {
            log.error("获取指标数据集异常", e);
        }
        return obj;
    }


    /**
     * 整理规则模板的数据，根据模板ID获取模板具体规则内容
     *
     * @param
     * @return MAP key为模板ID,value是规则集
     * @throws
     * @author ZHAOXA
     */
    private Map<Long, Object> getRuleGroupMap() {
        try {
            Map<Long, Object> returnMap = new HashMap<>();
            List<RuleTemplate> ruleTemplates = ruleTemplateMapper.selectByMap(null);
            for (RuleTemplate tem : ruleTemplates) {
                Map<String, Object> map = new HashMap<>();
                QueryWrapper<RuleGroup> groupWrapper = new QueryWrapper<>();
                groupWrapper.eq("template_id", tem.getId());
                groupWrapper.eq("is_copy", NoEn.NO1.valueInt());
                List<RuleGroup> copyGroups = ruleGroupMapper.selectList(groupWrapper);
                for (RuleGroup group : copyGroups) {
                    QueryWrapper<RuleBase> baseWrapper = new QueryWrapper<>();
                    baseWrapper.eq("group_id", group.getId());
                    baseWrapper.orderByDesc("is_unlimited");
                    group.setRuleBaseList(ruleBaseMapper.selectList(baseWrapper));
                }
                map.put("isCopy", copyGroups);
                groupWrapper = new QueryWrapper<>();
                groupWrapper.eq("template_id", tem.getId());
                groupWrapper.eq("is_copy", NoEn.NO0.valueInt());
                List<RuleGroup> notCopyGroups = ruleGroupMapper.selectList(groupWrapper);
                for (RuleGroup group : notCopyGroups) {
                    QueryWrapper<RuleBase> baseWrapper = new QueryWrapper<>();
                    baseWrapper.eq("group_id", group.getId());
                    baseWrapper.orderByDesc("is_unlimited");
                    group.setRuleBaseList(ruleBaseMapper.selectList(baseWrapper));
                }
                map.put("notCopy", notCopyGroups);
                map.put("type", tem.getMediaType());
                returnMap.put(tem.getId(), map);
            }
            return returnMap;
        } catch (Exception e) {
            log.error("获取模板规则组集合异常", e);
        }
        return null;
    }


    /**
     * 获取指标数据
     *
     * @param
     * @return java.util.List<org.json.JSONObject>
     * @throws
     * @author ZHAOXA
     */
    private JSONObject getRuleData(Long accountId) {
        try {
            return ruleDataAccountService.getRuleDataByAccountId(accountId);
        } catch (Exception e) {
            log.error("获取匹配数据集异常", e);
        }
        return null;
    }

    /**
     * 创建规则集
     *
     * @param requestJson
     * @return
     */


    @Override
    public JSONObject createRuleGroup(com.alibaba.fastjson.JSONObject requestJson) {
        JSONObject returnJson = new JSONObject();
        try {
            Long templateId = requestJson.getLong("templateId");
            if (Check.isNull(templateId)) {
                throw new Exception("请选择需要创建的规则模板id");
            }
            RuleTemplate template = ruleTemplateMapper.selectById(templateId);
            if (Check.isNull(template)) {
                throw new Exception("未获取到对应的规则模板详细情");
            }

            JSONArray ruleList = requestJson.getJSONArray("ruleList");
            if (Check.isNull(ruleList)) {
                throw new Exception("请传入具体规则");
            }
            QueryWrapper<RuleAccountTemplate> templateQueryWrapper = new QueryWrapper<>();
            templateQueryWrapper.eq("template_id", templateId);
            List<RuleAccountTemplate> accountList = ruleAccountTemplateService.list(templateQueryWrapper);

            for (int i = 0; i < ruleList.size(); i++) {
                JSONObject groupJson = ruleList.getJSONObject(i);
                JSONArray ruleDetail = groupJson.getJSONArray("ruleDetail");
                if (Check.isNull(ruleDetail)) {
                    throw new Exception("规则组下指标不能为空");
                }

                Integer isCopy = groupJson.getInteger("isCopy");
                String batchId = null;
                if (isCopy == 1) {
                    batchId = UUID.randomUUID().toString().replace("-", "");

                }
                JSONArray ruleIds = new JSONArray();
                JSONArray thresholdIds = new JSONArray();
                for (int j = 0; j < ruleDetail.size(); j++) {
                    JSONObject ruleDetailJson = ruleDetail.getJSONObject(j);
                    RuleBase ruleBase = new RuleBase();
                    ruleBase.setRuleName(ruleDetailJson.getString("ruleName"));
                    ruleBase.setIndicatorCode(ruleDetailJson.getString("indicatorCode"));
                    ruleBase.setRuleCondition(ruleDetailJson.getString("ruleCondition"));
                    ruleBase.setThreshold(ruleDetailJson.getString("threshold"));
                    ruleBase.setVariableType(ruleDetailJson.getInteger("variableType"));
                    ruleBase.setRuleDimension(ruleDetailJson.getString("ruleDimension"));
                    ruleBase.setJudgeFormat(ruleDetailJson.getInteger("judgeFormat"));
                    ruleBase.setIsUnlimited(ruleDetailJson.getInteger("isUnlimited"));
                    int insert = ruleBaseMapper.insert(ruleBase);    // 添加基础规则

                    if (insert > 0) {
                        if (!Check.isNull(accountList)) {
                            for (RuleAccountTemplate accountTemplate : accountList) {
                                Long accountId = accountTemplate.getAccountId();
                                QueryWrapper<RuleAccountThreshold> thresholdQueryWrapper = new QueryWrapper<>();
                                thresholdQueryWrapper.eq("account_id", accountId);
                                thresholdQueryWrapper.eq("rule_id", ruleBase.getId());
                                thresholdQueryWrapper.last("limit 1");
                                RuleAccountThreshold accountThreshold = ruleAccountThresholdMapper.selectOne(thresholdQueryWrapper);
                                if (!Check.isNull(accountThreshold)) {
                                    continue;
                                }
                                RuleAccountThreshold threshold = new RuleAccountThreshold();
                                if (ruleBase.getVariableType() == 0) {
                                    threshold.setThreshold(ruleBase.getThreshold());
                                }
                                threshold.setAccountId(accountId);
                                if (isCopy == 1) {
                                    threshold.setBatchNo(batchId);
                                }
                                threshold.setRuleId(ruleBase.getId());
                                int thresholdInsert = ruleAccountThresholdMapper.insert(threshold);// 默认将新建的规则同步到已应用的账户下
                                if (thresholdInsert > 0) {
                                    thresholdIds.add(threshold.getId());
                                }
                            }
                        }
                        ruleIds.add(ruleBase.getId()); // 获取基本规则集
                    }
                }
                RuleGroup ruleGroup = new RuleGroup();
                ruleGroup.setRuleIds(ruleIds.toJSONString());
                ruleGroup.setRuleType(groupJson.getString("ruleType"));
                ruleGroup.setTemplateId(templateId);
                ruleGroup.setRuleRelationship(groupJson.getString("ruleRelationship"));
                ruleGroup.setGroupName(groupJson.getString("groupName"));
                ruleGroup.setRemark(groupJson.getString("remark"));
                ruleGroup.setIsCopy(groupJson.getInteger("isCopy"));
                ruleGroup.setIsRequired(groupJson.getInteger("isRequired"));
                boolean save = ruleGroupService.save(ruleGroup); // 新增规则组
                if (save) {
                    for (int j = 0; j < ruleIds.size(); j++) {
                        Long ruleId = ruleIds.getLong(j);
                        RuleBase updateRuleBase = new RuleBase();
                        updateRuleBase.setId(ruleId);
                        updateRuleBase.setGroupId(ruleGroup.getId());
                        ruleBaseMapper.updateById(updateRuleBase); // 组同步成功之后 基础规则关联到组id
                    }
                    for (int j = 0; j < thresholdIds.size(); j++) {
                        Long threshold = thresholdIds.getLong(j);
                        RuleAccountThreshold updateThreshold = new RuleAccountThreshold();
                        updateThreshold.setId(threshold);
                        updateThreshold.setGroupId(ruleGroup.getId());
                        ruleAccountThresholdMapper.updateById(updateThreshold); // 同步到阈值之后 阈值关联到组id

                    }
                    JSONArray groupIds = JSONArray.parseArray(template.getGroupIds());
                    groupIds.add(ruleGroup.getId());
                    template.setGroupIds(groupIds.toJSONString());
                    ruleTemplateMapper.updateById(template); // 将新增的规则组id 添加到规则模板的规则组id下
                }
            }

            returnJson.put("code", 0);
            returnJson.put("message", "添加成功");
        } catch (Exception e) {
            e.printStackTrace();
            returnJson.put("code", -1);
            returnJson.put("message", e.getMessage());

        }

        return returnJson;
    }


}
