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

import cn.com.ctop.alarm.modules.entity.AlarmEventMetric;
import cn.com.ctop.alarm.modules.entity.AlarmEventRule;
import cn.com.ctop.alarm.modules.entity.AlarmRuleCampaignRel;
import cn.com.ctop.alarm.modules.mapper.AlarmEventMetricMapper;
import cn.com.ctop.alarm.modules.mapper.AlarmEventRuleMapper;
import cn.com.ctop.alarm.modules.mapper.AlarmRuleCampaignRelMapper;
import cn.com.ctop.alarm.modules.service.IAlarmEventRuleService;
import cn.com.ctop.common.module.utils.Check;
import cn.com.ctop.kuaishou.modules.batch.entity.KuaiShouGroup;
import cn.com.ctop.kuaishou.modules.batch.mapper.KuaiShouCampaignMapper;
import cn.com.ctop.kuaishou.modules.batch.mapper.KuaiShouGroupMapper;
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.github.pagehelper.PageInfo;
import com.xxl.job.core.enums.NoEn;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 预警事件规则表
 * 完成Condition
 * CURRENT_TODAY_DATA
 *
 * @author jeecg-boot
 * @version V1.0
 * @date 2020-10-29
 */
@Transactional
@Service
public class AlarmEventRuleServiceImpl extends ServiceImpl<AlarmEventRuleMapper, AlarmEventRule> implements IAlarmEventRuleService {

    @Autowired
    private AlarmEventRuleMapper alarmEventRuleMapper;

    @Autowired
    private AlarmEventMetricMapper alarmEventMetricMapper;

    @Autowired
    private AlarmRuleCampaignRelMapper alarmRuleCampaignRelMapper;

    @Autowired
    private KuaiShouCampaignMapper kuaiShouCampaignMapper;

    @Autowired
    private KuaiShouGroupMapper kuaiShouGroupMapper;

    @Override
    public PageInfo<AlarmEventRule> selectListPage(AlarmEventRule alarmEventRule) {
        return new PageInfo<AlarmEventRule>(alarmEventRuleMapper.selectListPage(alarmEventRule));
    }

    @Override
    public void deleteById(Long id) {
        alarmEventRuleMapper.deleteById(id);
        alarmEventMetricMapper.deleteByRuleId(id);
        alarmRuleCampaignRelMapper.deleteByRuleId(id);
    }

    @Override
    public PageInfo<AlarmEventRule> queryRunningRecordPage(AlarmEventRule alarmEventRule) {
        return new PageInfo<AlarmEventRule>(alarmEventRuleMapper.queryRunningRecordPage(alarmEventRule));
    }

    @Override
    public Result<Object> addAlarmEventRule(JSONObject obj) {
        Map<String, Object> map = new HashMap<>();
        map.put("account_id", obj.getLong("accountId"));
        map.put("event_rule_name", obj.getString("eventRuleName"));
        if (!Check.isNull(alarmEventRuleMapper.selectByMap(map))) {
            return Result.error(1, "添加失败，重复的规则名，请重新输入");
        }

        //1。新增rule表
        AlarmEventRule rule = new AlarmEventRule();
        reSetRuleEntity(rule, obj);
        JSONArray metrics = obj.getJSONArray("alarmEventMetric");
        if (Check.isNull(metrics)) {
            return Result.error(1, "请选择具体规则指标");
        }
        rule.setEventRuleStatus(NoEn.NO1.valueStr());//默认新增为激活状态
        alarmEventRuleMapper.insert(rule);
        //2。新增metric表
        AlarmEventMetric metric = null;
        for (int i = 0; i < metrics.size(); i++) {
            metric = new AlarmEventMetric();
            reSetMetricEntity(metric, metrics.getJSONObject(i), rule.getEventRuleId());
            alarmEventMetricMapper.insert(metric);
        }
        //2。新增rel表
        //通过指定选择应用
        JSONArray rels = obj.getJSONArray("rel");
        if (!Check.isNull(rels)) {
            addRelByIds(rels, rule);
        }
        return new Result<>().success("添加成功！");
    }

    @Override
    public Result<Object> editAlarmEventRule(JSONObject obj) {
        AlarmEventRule alarmEventRule = new AlarmEventRule();
        alarmEventRule.setUnitId(obj.getLong("eventRuleId"));
        alarmEventRule.setAccountId(obj.getLong("accountId"));
        alarmEventRule.setEventRuleName(obj.getString("eventRuleName"));
        if (!Check.isNull(alarmEventRuleMapper.selectListPage(alarmEventRule))) {
            return Result.error(1, "修改失败，重复的规则名，请重新输入");
        }
        //1.更改rule表
        AlarmEventRule rule = new AlarmEventRule();
        reSetRuleEntity(rule, obj);
        QueryWrapper<AlarmEventRule> ruleWrapper = new QueryWrapper<>();
        ruleWrapper.eq("event_rule_id", obj.getLong("eventRuleId"));
        alarmEventRuleMapper.update(rule, ruleWrapper);
        rule.setEventRuleId(obj.getLong("eventRuleId"));
        //2.更改metric表
        JSONArray metrics = obj.getJSONArray("alarmEventMetric");
        if (Check.isNull(metrics)) {
            return Result.error(1, "请选择具体规则指标");
        }
        AlarmEventMetric metric = null;
        QueryWrapper<AlarmEventMetric> metricWrapper = null;
        for (int i = 0; i < metrics.size(); i++) {
            JSONObject mo = metrics.getJSONObject(i);
            metric = new AlarmEventMetric();
            reSetMetricEntity(metric, mo, rule.getEventRuleId());
            metricWrapper = new QueryWrapper<>();
            metricWrapper.eq("event_metric_id", mo.getLong("eventMetricId"));
            metricWrapper.eq("event_rule_id", obj.getLong("eventRuleId"));
            alarmEventMetricMapper.update(metric, metricWrapper);
        }
        //3.更改rel表
        //通过指定，传参ids绑定应用
        JSONArray rels = obj.getJSONArray("rel");
        if (!Check.isNull(rels)) {
            alarmRuleCampaignRelMapper.deleteByRuleId(rule.getEventRuleId());
            addRelByIds(rels, rule);
        }
        return new Result<>().success("修改成功！");
    }

    @Override
    public AlarmEventRule selectById(Long id) {
        AlarmEventRule alarmEventRule = alarmEventRuleMapper.queryById(id);
        if (Check.isNull(alarmEventRule)) {
            return null;
        }
        alarmEventRule.setAlarmEventMetrics(alarmEventMetricMapper.selectByEventRuleId(id));
        if (("CAMPAIGN".equals(alarmEventRule.getEventRuleLevel()) || "UNIT".equals(alarmEventRule.getEventRuleLevel())) && !NoEn.NO1.valueStr().equals(alarmEventRule.getAppStatus())) {
            alarmEventRule.setRel(alarmRuleCampaignRelMapper.selectByRuleId(id));
        }
        return alarmEventRule;
    }

    //通过状态+level绑定应用
    private void addRelByStatus(AlarmEventRule rule, Long campaignId) {
        if ("CAMPAIGN".equals(rule.getEventRuleLevel())) {
            List<Long> ids = kuaiShouCampaignMapper.queryIdsByPutStatus(rule.getAccountId(), NoEn.NO1.valueStr());
            if (Check.isNull(ids)) {
                return;
            }
            for (Long id : ids) {
                AlarmRuleCampaignRel relEntity = new AlarmRuleCampaignRel();
                relEntity.setEventRuleId(rule.getEventRuleId());
                relEntity.setAccountId(rule.getAccountId());
                relEntity.setEventRuleLevel(rule.getEventRuleLevel());
                relEntity.setCampaignId(id);
                alarmRuleCampaignRelMapper.insert(relEntity);
            }
        }
        if ("UNIT".equals(rule.getEventRuleLevel())) {
            Map<String, Object> map = new HashMap<>();
            map.put("put_status", NoEn.NO1.valueStr());
            map.put("account_id", rule.getAccountId());
            if (Check.isNull(campaignId)) {
                map.put("campaign_id", campaignId);
            }
            List<KuaiShouGroup> kuaiShouGroups = kuaiShouGroupMapper.selectByMap(map);
            if (Check.isNull(kuaiShouGroups)) {
                return;
            }
            for (KuaiShouGroup kuaiShouGroup : kuaiShouGroups) {
                AlarmRuleCampaignRel relEntity = new AlarmRuleCampaignRel();
                relEntity.setEventRuleId(rule.getEventRuleId());
                relEntity.setAccountId(rule.getAccountId());
                relEntity.setEventRuleLevel(rule.getEventRuleLevel());
                relEntity.setCampaignId(kuaiShouGroup.getCampaignId());
                relEntity.setUnitId(kuaiShouGroup.getUnitId());
                alarmRuleCampaignRelMapper.insert(relEntity);
            }
        }
    }

    //通过指定，传参IDS绑定应用
    private void addRelByIds(JSONArray rels, AlarmEventRule rule) {
        for (int k = 0; k < rels.size(); k++) {
            AlarmRuleCampaignRel relEntity = new AlarmRuleCampaignRel();
            JSONObject rel = rels.getJSONObject(k);
            relEntity.setEventRuleId(rule.getEventRuleId());
            relEntity.setAccountId(rule.getAccountId());
            relEntity.setEventRuleLevel(rule.getEventRuleLevel());
            relEntity.setCampaignId(rel.getLong("campaignId"));
            relEntity.setUnitId(rel.getLong("unitId"));
            alarmRuleCampaignRelMapper.insert(relEntity);
        }
    }

    /**
     * 规则实体类封装
     * Message template
     *
     * @param
     * @return void
     * @throws
     * @author ZHAOXA
     */
    private void reSetRuleEntity(AlarmEventRule rule, JSONObject obj) {
        Long accountId = obj.getLong("accountId");
        if (!Check.isNull(accountId)) {
            rule.setAccountId(accountId);
        }
        Long campaignId = obj.getLong("campaignId");
        if (!Check.isNull(campaignId)) {
            rule.setCampaignId(campaignId);
        }
        String eventRuleName = obj.getString("eventRuleName");
        if (!Check.isNull(eventRuleName)) {
            rule.setEventRuleName(eventRuleName);
        }
        String eventRuleLevel = obj.getString("eventRuleLevel");
        if (!Check.isNull(eventRuleLevel)) {
            rule.setEventRuleLevel(eventRuleLevel);
        }
        String checkFrequency = obj.getString("checkFrequency");
        if (!Check.isNull(checkFrequency)) {
            rule.setCheckFrequency(checkFrequency);
        }
        String metricValueCode = obj.getString("metricValueCode");
        if (!Check.isNull(metricValueCode)) {
            rule.setMetricValueCode(metricValueCode);
        }
        String metricValueName = obj.getString("metricValueName");
        if (!Check.isNull(metricValueName)) {
            rule.setMetricValueName(metricValueName);
        }
        String processMethod = obj.getString("processMethod");
        if (!Check.isNull(processMethod)) {
            rule.setProcessMethod(processMethod);
        }
        String eventRuleStatus = obj.getString("eventRuleStatus");
        if (!Check.isNull(eventRuleStatus)) {
            rule.setEventRuleStatus(eventRuleStatus);
        }
        rule.setCreaterId(obj.getString("createrId"));
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        if (!Check.isNull(sysUser)) {
            rule.setCreaterId(sysUser.getId());
        }
        if (!Check.isNull(obj.getString("appStatus")) && Check.isNull(obj.getJSONArray("rel"))) {
            rule.setAppStatus(obj.getString("appStatus"));
        }
    }

    /**
     * 填充规则详细实体类
     *
     * @param
     * @return void
     * @throws
     * @author ZHAOXA
     */
    private void reSetMetricEntity(AlarmEventMetric metric, JSONObject mo, Long ruleId) {
        metric.setEventRuleId(ruleId);
        String valueCode = mo.getString("metricValueCode");
        if (!Check.isNull(valueCode)) {
            metric.setMetricValueCode(valueCode);
        }
        String valueName = mo.getString("metricValueName");
        if (!Check.isNull(valueName)) {
            metric.setMetricValueName(valueName);
        }
        String judgeType = mo.getString("judgeType");
        if (!Check.isNull(judgeType)) {
            metric.setJudgeType(judgeType);
        }
        String judgeMethod = mo.getString("judgeMethod");
        if (!Check.isNull(judgeMethod)) {
            metric.setJudgeMethod(judgeMethod);
        }
        String threshold = mo.getString("threshold");
        if (!Check.isNull(threshold)) {
            metric.setThreshold(threshold);
        }
        String minThreshold = mo.getString("minThreshold");
        if (!Check.isNull(minThreshold)) {
            metric.setMinThreshold(minThreshold);
        }
        String dataRange = mo.getString("dataRange");
        if (!Check.isNull(dataRange)) {
            metric.setDataRange(dataRange);
        }
    }

}
