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

import cn.com.ctop.alarm.modules.entity.*;
import cn.com.ctop.alarm.modules.mapper.RuleBaseMapper;
import cn.com.ctop.alarm.modules.mapper.RuleTemplateMapper;
import cn.com.ctop.alarm.modules.service.*;
import cn.com.ctop.common.module.utils.Check;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 规则模板
 *
 * @author jeecg-boot
 * @version V1.0
 * @date 2020-11-15
 */
@Slf4j
@Service
public class RuleTemplateServiceImpl extends ServiceImpl<RuleTemplateMapper, RuleTemplate> implements IRuleTemplateService {
    @Autowired
    private IRuleBaseService ruleBaseService;

    @Autowired
    private RuleBaseMapper ruleBaseMapper;

    @Autowired
    private IRuleGroupService ruleGroupService;

    @Autowired
    private RuleTemplateMapper ruleTemplateMapper;

    @Autowired
    private IRuleIndicatorService ruleIndicatorService;

    @Autowired
    private IRuleAccountThresholdService accountThresholdService;

    /**
     * 创建规则模板
     *
     * @param requestJson
     * @return
     */
    @Override
    public JSONObject createTemplate(JSONObject requestJson) {
        JSONObject returnJson = new JSONObject();
        try {
            Integer mediaType = requestJson.getInteger("mediaType");
            if (Check.isNull(mediaType)) {
                throw new Exception("请传入媒体类型");
            }
            String templateName = requestJson.getString("templateName");
            if (Check.isNull(templateName)) {
                throw new Exception("请传入模板名称");
            }
            QueryWrapper<RuleTemplate> queryQueryWrapper = new QueryWrapper<>();
            queryQueryWrapper.eq("media_type", mediaType);
            queryQueryWrapper.eq("template_name", templateName);
            RuleTemplate ruleTemplate = this.getOne(queryQueryWrapper);
            if (!Check.isNull(ruleTemplate)) {
                throw new Exception("同媒体下模板名称不能相同");
            }
            RuleTemplate template = new RuleTemplate();
            template.setMediaType(mediaType);
            template.setTemplateName(templateName);
            JSONArray groupIds = new JSONArray();
            JSONArray ruleList = requestJson.getJSONArray("ruleList"); // 模板规则详情
            if (Check.isNull(ruleList)) {
                throw new Exception("模板具体规则不能为空");
            }
            for (int i = 0; i < ruleList.size(); i++) {
                JSONObject ruleGroupJson = ruleList.getJSONObject(i);
                if (!Check.isNull(ruleGroupJson)) {
                    JSONArray ruleDetailArr = ruleGroupJson.getJSONArray("ruleDetail");
                    if (!Check.isNull(ruleDetailArr)) {
                        JSONArray ruleIds = new JSONArray();
                        for (int j = 0; j < ruleDetailArr.size(); j++) {
                            JSONObject ruleDetailJson = ruleDetailArr.getJSONObject(j);
                            if (!Check.isNull(ruleDetailJson)) {
                                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) {
                                    ruleIds.add(ruleBase.getId());
                                }
                            }
                        }
                        RuleGroup ruleGroup = new RuleGroup();
                        ruleGroup.setRuleIds(ruleIds.toJSONString());
                        ruleGroup.setRuleType(ruleGroupJson.getString("ruleType"));
                        ruleGroup.setRuleRelationship(ruleGroupJson.getString("ruleRelationship"));
                        ruleGroup.setGroupName(ruleGroupJson.getString("groupName"));
                        ruleGroup.setRemark(ruleGroupJson.getString("remark"));
                        ruleGroup.setIsCopy(ruleGroupJson.getInteger("isCopy"));
                        ruleGroup.setIsRequired(ruleGroupJson.getInteger("isRequired"));
                        ruleGroup.setSendType(ruleGroupJson.getString("sendType"));
                        ruleGroup.setOperate(ruleGroupJson.getString("operate"));
                        boolean save = ruleGroupService.save(ruleGroup);
                        if (save) {
                            String ruleIdsArrStr = ruleGroup.getRuleIds();
                            JSONArray array = JSONArray.parseArray(ruleIdsArrStr);
                            if (!Check.isNull(array)) {
                                for (int j = 0; j < array.size(); j++) {
                                    Long ruleId = array.getLong(j);
                                    RuleBase updateBase = new RuleBase();
                                    updateBase.setId(ruleId);
                                    updateBase.setGroupId(ruleGroup.getId());
                                    ruleBaseService.updateById(updateBase);
                                }
                            }
                            groupIds.add(ruleGroup.getId());
                        }
                    }
                }
            }
            template.setGroupIds(groupIds.toJSONString());
            boolean save = this.save(template);
            if (save) {
                String groupIdsArrStr = template.getGroupIds();
                JSONArray groupIdsArr = JSONArray.parseArray(groupIdsArrStr);
                if (!Check.isNull(groupIdsArr)) {
                    for (int i = 0; i < groupIdsArr.size(); i++) {
                        Long groupId = groupIdsArr.getLong(i);
                        RuleGroup updateRuleGroup = new RuleGroup();
                        updateRuleGroup.setId(groupId);
                        updateRuleGroup.setTemplateId(template.getId());
                        ruleGroupService.updateById(updateRuleGroup);
                    }

                }
            }
            log.info("创建规则模板成功，模板名称：{}", templateName);
            returnJson.put("code", 0);
            returnJson.put("message", "创建成功");


        } catch (Exception e) {
            e.printStackTrace();
            returnJson.put("code", -1);
            returnJson.put("message", e.getMessage());
        }

        return returnJson;
    }


    /**
     * 获取模板详情
     *
     * @param id
     * @return
     */


    @Override
    public JSONObject queryDetailById(String id) throws Exception {
        JSONObject returnJson = new JSONObject();
        RuleTemplate template = ruleTemplateMapper.selectById(id);
        if (Check.isNull(template)) {
            throw new Exception("获取模板基本信息为空");
        }
        returnJson.put("templateId", template.getId());
        returnJson.put("templateName", template.getTemplateName());
        returnJson.put("mediaType", template.getMediaType());
        JSONArray groupIds = JSONArray.parseArray(template.getGroupIds());
        if (!Check.isNull(groupIds)) {
            JSONArray ruleList = new JSONArray();
            for (int i = 0; i < groupIds.size(); i++) {
                Long groupId = groupIds.getLong(i);
                RuleGroup group = ruleGroupService.getById(groupId);
                if (Check.isNull(group)) {
                    continue;
                }
                JSONObject groupJson = new JSONObject();
                groupJson.put("groupId", group.getId());
                groupJson.put("groupName", group.getGroupName());
                groupJson.put("ruleType", group.getRuleType());
                groupJson.put("ruleRelationship", group.getRuleRelationship());
                groupJson.put("remark", group.getRemark());
                groupJson.put("operate", group.getOperate());
                groupJson.put("sendType", group.getSendType());
                groupJson.put("isCopy", group.getIsCopy());
                groupJson.put("isRequired", group.getIsRequired());
                JSONArray ruleIds = JSONArray.parseArray(group.getRuleIds());
                if (Check.isNull(ruleIds)) {
                    continue;
                }
                JSONArray ruleDetail = new JSONArray();
                for (int j = 0; j < ruleIds.size(); j++) {
                    Long ruleId = ruleIds.getLong(j);
                    RuleBase ruleBase = ruleBaseService.getById(ruleId);
                    if (Check.isNull(ruleBase)) {
                        continue;
                    }
                    JSONObject ruleJson = new JSONObject();
                    ruleJson.put("ruleId", ruleBase.getId());
                    ruleJson.put("ruleName", ruleBase.getRuleName());
                    ruleJson.put("judgeFormat", ruleBase.getJudgeFormat());
                    ruleJson.put("indicatorCode", ruleBase.getIndicatorCode());
                    ruleJson.put("ruleCondition", ruleBase.getRuleCondition());
                    ruleJson.put("threshold", ruleBase.getThreshold());
                    ruleJson.put("ruleDimension", ruleBase.getRuleDimension());
                    ruleJson.put("variableType", ruleBase.getVariableType());
                    ruleJson.put("isUnlimited", ruleBase.getIsUnlimited());
                    /**
                     * 查询指标对应信息
                     */
                    QueryWrapper<RuleIndicator> indicatorQueryWrapper = new QueryWrapper<>();
                    indicatorQueryWrapper.eq("code", ruleBase.getIndicatorCode());
                    indicatorQueryWrapper.eq("dimension", ruleBase.getRuleDimension());
                    indicatorQueryWrapper.eq("media_type", template.getMediaType());
                    indicatorQueryWrapper.last("limit 1");
                    RuleIndicator ruleIndicator = ruleIndicatorService.getOne(indicatorQueryWrapper);
                    if (!Check.isNull(ruleIndicator)) {
                        ruleJson.put("dataType", ruleIndicator.getDataType());
                        ruleJson.put("dictId", ruleIndicator.getDictId());
                        ruleJson.put("dataUnit", ruleIndicator.getDataUnit());
                        ruleJson.put("name", ruleIndicator.getName());
                        ruleJson.put("modelType", ruleIndicator.getModelType());
                    }

                    ruleDetail.add(ruleJson);
                }
                groupJson.put("ruleDetail", ruleDetail);
                ruleList.add(groupJson);
            }
            returnJson.put("ruleList", ruleList);
        }


        return returnJson;
    }


    /**
     * 根据 账户id 模板id 查询模板详情
     *
     * @param accountId
     * @param templateId
     * @return
     */
    @Override
    public JSONObject queryDetailByAccountIdAndTemplateId(Long accountId, Long templateId) throws Exception {
        JSONObject returnJson = new JSONObject();
        RuleTemplate template = ruleTemplateMapper.selectById(templateId);
        if (Check.isNull(template)) {
            throw new Exception("获取模板基本信息为空");
        }

        returnJson.put("templateId", template.getId());
        returnJson.put("templateName", template.getTemplateName());
        returnJson.put("mediaType", template.getMediaType());
        JSONArray groupIds = JSONArray.parseArray(template.getGroupIds());
        if (Check.isNull(groupIds)) {
            throw new Exception("未获取规则集");
        }
        JSONArray ruleList = new JSONArray();
        for (int i = 0; i < groupIds.size(); i++) {
            Long groupId = groupIds.getLong(i);
            RuleGroup group = ruleGroupService.getById(groupId);
            if (Check.isNull(group)) {
                continue;
            }
            JSONObject groupJson = new JSONObject();
            groupJson.put("groupId", group.getId());
            groupJson.put("groupName", group.getGroupName());
            groupJson.put("ruleType", group.getRuleType());
            groupJson.put("ruleRelationship", group.getRuleRelationship());
            groupJson.put("remark", group.getRemark());
            groupJson.put("operate", group.getOperate());
            groupJson.put("sendType", group.getSendType());
            groupJson.put("isCopy", group.getIsCopy());
            groupJson.put("isRequired", group.getIsRequired());
            JSONArray ruleDetail = new JSONArray();

            if (group.getIsCopy() == 0) { // 规则不可复制
                JSONArray ruleIds = JSONArray.parseArray(group.getRuleIds());
                if (Check.isNull(ruleIds)) {
                    continue;
                }
                for (int j = 0; j < ruleIds.size(); j++) {
                    Long ruleId = ruleIds.getLong(j);
                    RuleBase ruleBase = ruleBaseService.getById(ruleId); // 查询基础规则信息
                    if (Check.isNull(ruleBase)) {
                        continue;
                    }
                    JSONObject ruleJson = new JSONObject();
                    ruleJson.put("ruleId", ruleBase.getId());
                    ruleJson.put("ruleName", ruleBase.getRuleName());
                    ruleJson.put("judgeFormat", ruleBase.getJudgeFormat());
                    ruleJson.put("indicatorCode", ruleBase.getIndicatorCode());
                    ruleJson.put("ruleCondition", ruleBase.getRuleCondition());
                    QueryWrapper<RuleAccountThreshold> accountThresholdQueryWrapper = new QueryWrapper<>();
                    accountThresholdQueryWrapper.eq("account_id", accountId);
                    accountThresholdQueryWrapper.eq("rule_id", ruleId);
                    accountThresholdQueryWrapper.eq("group_id", groupId);
                    RuleAccountThreshold threshold = accountThresholdService.getOne(accountThresholdQueryWrapper); // 查询基础规则绑定的阈值
                    if (!Check.isNull(threshold)) {
                        String value = threshold.getThreshold();
                        if (!Check.isNull(value)) {
                            if (value.contains("[") && value.contains("]")) {
                                ruleJson.put("threshold", JSONArray.parseArray(value));
                            } else {
                                ruleJson.put("threshold", value);
                            }
                        } else {
                            ruleJson.put("threshold", null);
                        }
                    } else {
                        ruleJson.put("threshold", null);
                    }

                    ruleJson.put("ruleDimension", ruleBase.getRuleDimension());
                    ruleJson.put("variableType", ruleBase.getVariableType());
                    ruleJson.put("isUnlimited", ruleBase.getIsUnlimited());
                    /**
                     * 查询指标对应信息
                     */
                    QueryWrapper<RuleIndicator> indicatorQueryWrapper = new QueryWrapper<>();
                    indicatorQueryWrapper.eq("code", ruleBase.getIndicatorCode());
                    indicatorQueryWrapper.eq("dimension", ruleBase.getRuleDimension());
                    indicatorQueryWrapper.eq("media_type", template.getMediaType());
                    indicatorQueryWrapper.last("limit 1");
                    RuleIndicator ruleIndicator = ruleIndicatorService.getOne(indicatorQueryWrapper);  // 查询指标的详情信息
                    if (!Check.isNull(ruleIndicator)) {
                        ruleJson.put("dataType", ruleIndicator.getDataType());
                        ruleJson.put("dictId", ruleIndicator.getDictId());
                        ruleJson.put("dataUnit", ruleIndicator.getDataUnit());
                        ruleJson.put("name", ruleIndicator.getName());
                        ruleJson.put("modelType", ruleIndicator.getModelType());
                        ruleJson.put("requestUrl", ruleIndicator.getRequestUrl());
                    }

                    ruleDetail.add(ruleJson);
                }
                groupJson.put("ruleDetail", ruleDetail);
            } else if (group.getIsCopy() == 1) {  // 如果规则可以复制

                List<String> batchNoList = accountThresholdService.getBatchNo(accountId, groupId); // 查询批次号
                if (Check.isNull(batchNoList)) {
                    continue;
                }
                for (int j = 0; j < batchNoList.size(); j++) {
                    String batchNo = (String) batchNoList.get(j);
                    if (Check.isNull(batchNo)) {
                        continue;
                    }
                    JSONArray ruleArr = new JSONArray();
                    QueryWrapper<RuleAccountThreshold> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("account_id", accountId);
                    queryWrapper.eq("group_id", groupId);
                    queryWrapper.eq("batch_no", batchNo);
                    List<RuleAccountThreshold> list = accountThresholdService.list(queryWrapper); // 根据批次号查询绑定的基础规则阈值集合
                    if (Check.isNull(list)) {
                        continue;
                    }
                    for (RuleAccountThreshold threshold : list) {
                        RuleBase ruleBase = ruleBaseService.getById(threshold.getRuleId()); // 根据阈值集合ruleId 查询基础规则信息
                        if (Check.isNull(ruleBase)) {
                            continue;
                        }
                        JSONObject ruleJson = new JSONObject();
                        ruleJson.put("ruleId", ruleBase.getId());
                        ruleJson.put("ruleName", ruleBase.getRuleName());
                        ruleJson.put("judgeFormat", ruleBase.getJudgeFormat());
                        ruleJson.put("indicatorCode", ruleBase.getIndicatorCode());
                        ruleJson.put("ruleCondition", ruleBase.getRuleCondition());
                        String value = threshold.getThreshold();
                        if (!Check.isNull(value)) {
                            if (value.contains("[") && value.contains("]")) {
                                ruleJson.put("threshold", JSONArray.parseArray(value));
                            } else {
                                ruleJson.put("threshold", value);
                            }
                        } else {
                            ruleJson.put("threshold", null);
                        }
                        ruleJson.put("ruleDimension", ruleBase.getRuleDimension());
                        ruleJson.put("variableType", ruleBase.getVariableType());
                        ruleJson.put("isUnlimited", ruleBase.getIsUnlimited());
                        /**
                         * 查询指标对应信息
                         */
                        QueryWrapper<RuleIndicator> indicatorQueryWrapper = new QueryWrapper<>();
                        indicatorQueryWrapper.eq("code", ruleBase.getIndicatorCode());
                        indicatorQueryWrapper.eq("media_type", template.getMediaType());
                        indicatorQueryWrapper.eq("dimension", ruleBase.getRuleDimension());
                        indicatorQueryWrapper.last("limit 1");
                        RuleIndicator ruleIndicator = ruleIndicatorService.getOne(indicatorQueryWrapper); // 查询基础规则的指标信息
                        if (!Check.isNull(ruleIndicator)) {
                            ruleJson.put("dataType", ruleIndicator.getDataType());
                            ruleJson.put("dictId", ruleIndicator.getDictId());
                            ruleJson.put("dataUnit", ruleIndicator.getDataUnit());
                            ruleJson.put("name", ruleIndicator.getName());
                            ruleJson.put("modelType", ruleIndicator.getModelType());
                        }
                        ruleArr.add(ruleJson);
                    }

                    ruleDetail.add(ruleArr);
                }
                groupJson.put("ruleDetail", ruleDetail);
            }
            ruleList.add(groupJson);
        }
        returnJson.put("ruleList", ruleList);
        return returnJson;
    }

    @Override
    public JSONObject previewTemplate(String id) throws Exception {
        JSONObject returnJson = new JSONObject();
        RuleTemplate template = ruleTemplateMapper.selectById(id);
        if (Check.isNull(ruleTemplateMapper)) {
            throw new Exception("获取模板基本信息为空");
        }
        returnJson.put("templateId", template.getId());
        returnJson.put("templateName", template.getTemplateName());
        returnJson.put("mediaType", template.getMediaType());
        JSONArray groupIds = JSONArray.parseArray(template.getGroupIds());
        if (Check.isNull(groupIds)) {
            throw new Exception("未获取规则集");
        }
        JSONArray ruleList = new JSONArray();
        for (int i = 0; i < groupIds.size(); i++) {
            Long groupId = groupIds.getLong(i);
            RuleGroup group = ruleGroupService.getById(groupId);
            if (Check.isNull(group)) {
                continue;
            }
            JSONObject groupJson = new JSONObject();
            groupJson.put("groupId", group.getId());
            groupJson.put("groupName", group.getGroupName());
            groupJson.put("ruleType", group.getRuleType());
            groupJson.put("ruleRelationship", group.getRuleRelationship());
            groupJson.put("remark", group.getRemark());
            groupJson.put("operate", group.getOperate());
            groupJson.put("sendType", group.getSendType());
            groupJson.put("isCopy", group.getIsCopy());
            groupJson.put("isRequired", group.getIsRequired());
            JSONArray ruleIds = JSONArray.parseArray(group.getRuleIds());
            if (Check.isNull(ruleIds)) {
                continue;
            }
            JSONArray ruleDetail = new JSONArray();
            if (group.getIsCopy() == 0) {
                for (int j = 0; j < ruleIds.size(); j++) {
                    Long ruleId = ruleIds.getLong(j);
                    RuleBase ruleBase = ruleBaseService.getById(ruleId);
                    if (Check.isNull(ruleBase)) {
                        continue;
                    }
                    JSONObject ruleJson = new JSONObject();
                    ruleJson.put("ruleId", ruleBase.getId());
                    ruleJson.put("ruleName", ruleBase.getRuleName());
                    ruleJson.put("judgeFormat", ruleBase.getJudgeFormat());
                    ruleJson.put("indicatorCode", ruleBase.getIndicatorCode());
                    ruleJson.put("ruleCondition", ruleBase.getRuleCondition());
                    ruleJson.put("threshold", ruleBase.getThreshold());
                    ruleJson.put("ruleDimension", ruleBase.getRuleDimension());
                    ruleJson.put("variableType", ruleBase.getVariableType());
                    ruleJson.put("isUnlimited", ruleBase.getIsUnlimited());
                    /**
                     * 查询指标对应信息
                     */
                    QueryWrapper<RuleIndicator> indicatorQueryWrapper = new QueryWrapper<>();
                    indicatorQueryWrapper.eq("code", ruleBase.getIndicatorCode());
                    indicatorQueryWrapper.eq("dimension", ruleBase.getRuleDimension());
                    indicatorQueryWrapper.eq("media_type", template.getMediaType());
                    indicatorQueryWrapper.last("limit 1");
                    RuleIndicator ruleIndicator = ruleIndicatorService.getOne(indicatorQueryWrapper);
                    if (!Check.isNull(ruleIndicator)) {
                        ruleJson.put("dataType", ruleIndicator.getDataType());
                        ruleJson.put("dictId", ruleIndicator.getDictId());
                        ruleJson.put("dataUnit", ruleIndicator.getDataUnit());
                        ruleJson.put("name", ruleIndicator.getName());
                        ruleJson.put("modelType", ruleIndicator.getModelType());
                        ruleJson.put("requestUrl", ruleIndicator.getRequestUrl());
                    }

                    ruleDetail.add(ruleJson);
                }
                groupJson.put("ruleDetail", ruleDetail);
            } else if (group.getIsCopy() == 1) {
                JSONArray array = new JSONArray();
                for (int j = 0; j < ruleIds.size(); j++) {
                    Long ruleId = ruleIds.getLong(j);
                    RuleBase ruleBase = ruleBaseService.getById(ruleId);
                    if (Check.isNull(ruleBase)) {
                        continue;
                    }
                    JSONObject ruleJson = new JSONObject();
                    ruleJson.put("ruleId", ruleBase.getId());
                    ruleJson.put("ruleName", ruleBase.getRuleName());
                    ruleJson.put("judgeFormat", ruleBase.getJudgeFormat());
                    ruleJson.put("indicatorCode", ruleBase.getIndicatorCode());
                    ruleJson.put("ruleCondition", ruleBase.getRuleCondition());
                    ruleJson.put("threshold", ruleBase.getThreshold());
                    ruleJson.put("ruleDimension", ruleBase.getRuleDimension());
                    ruleJson.put("variableType", ruleBase.getVariableType());
                    ruleJson.put("isUnlimited", ruleBase.getIsUnlimited());
                    /**
                     * 查询指标对应信息
                     */
                    QueryWrapper<RuleIndicator> indicatorQueryWrapper = new QueryWrapper<>();
                    indicatorQueryWrapper.eq("code", ruleBase.getIndicatorCode());
                    indicatorQueryWrapper.eq("dimension", ruleBase.getRuleDimension());
                    indicatorQueryWrapper.eq("media_type", template.getMediaType());
                    indicatorQueryWrapper.last("limit 1");
                    RuleIndicator ruleIndicator = ruleIndicatorService.getOne(indicatorQueryWrapper);
                    if (!Check.isNull(ruleIndicator)) {
                        ruleJson.put("dataType", ruleIndicator.getDataType());
                        ruleJson.put("dictId", ruleIndicator.getDictId());
                        ruleJson.put("dataUnit", ruleIndicator.getDataUnit());
                        ruleJson.put("name", ruleIndicator.getName());
                        ruleJson.put("modelType", ruleIndicator.getModelType());
                    }

                    array.add(ruleJson);
                }
                ruleDetail.add(array);
                groupJson.put("ruleDetail", ruleDetail);
            }
            ruleList.add(groupJson);
        }
        returnJson.put("ruleList", ruleList);
        return returnJson;
    }

}
