/*
 * 文 件 名:  AlarmRuleServiceImpl
 * 版    权:  华设设计集团股份有限公司
 * 描    述:  <描述>
 * 修 改 人:  lvwenbin
 * 修改时间:  2026/2/3
 * 跟踪单号:  <跟踪单号>
 * 修改单号:  <修改单号>
 * 修改内容:  <修改内容>
 */
package com.ruoyi.ems.service.impl;


import com.alibaba.fastjson2.JSON;
import com.huashe.common.utils.uuid.Seq;

import com.ruoyi.ems.domain.AlarmRule;
import com.ruoyi.ems.mapper.AlarmRuleMapper;
import com.ruoyi.ems.service.IAlarmRuleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 告警规则Service实现
 */
@Slf4j
@Service
public class AlarmRuleServiceImpl implements IAlarmRuleService {

    private static final String CACHE_NAME = "alarmRules";

    @Autowired
    private AlarmRuleMapper ruleMapper;

    @Override
    public AlarmRule selectById(Long id) {
        AlarmRule rule = ruleMapper.selectById(id);
        parseTargetScope(rule);
        return rule;
    }

    @Override
    @Cacheable(value = CACHE_NAME, key = "#ruleCode")
    public AlarmRule selectByRuleCode(String ruleCode) {
        AlarmRule rule = ruleMapper.selectByRuleCode(ruleCode);
        parseTargetScope(rule);
        return rule;
    }

    @Override
    public List<AlarmRule> selectList(AlarmRule query) {
        List<AlarmRule> list = ruleMapper.selectList(query);
        if (CollectionUtils.isNotEmpty(list)) {
            list.forEach(this::parseTargetScope);
        }
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = CACHE_NAME, allEntries = true)
    public int insert(AlarmRule rule) {
        // 生成规则代码
        if (StringUtils.isBlank(rule.getRuleCode())) {
            rule.setRuleCode("RULE_" + Seq.getId());
        }

        // 序列化目标范围
        if (CollectionUtils.isNotEmpty(rule.getTargetScopeList())) {
            rule.setTargetScope(JSON.toJSONString(rule.getTargetScopeList()));
        }

        // 默认值
        if (rule.getEnabled() == null) {
            rule.setEnabled(1);
        }
        if (rule.getUseForInspection() == null) {
            rule.setUseForInspection(1);
        }
        if (rule.getUseForRealtime() == null) {
            rule.setUseForRealtime(1);
        }
        if (rule.getRecoveryCheck() == null) {
            rule.setRecoveryCheck(1);
        }
        if (rule.getTriggerCount() == null) {
            rule.setTriggerCount(1);
        }
        if (rule.getCoolDown() == null) {
            rule.setCoolDown(300);
        }

        return ruleMapper.insert(rule);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = CACHE_NAME, allEntries = true)
    public int update(AlarmRule rule) {
        // 序列化目标范围
        if (rule.getTargetScopeList() != null) {
            rule.setTargetScope(JSON.toJSONString(rule.getTargetScopeList()));
        }
        return ruleMapper.update(rule);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = CACHE_NAME, allEntries = true)
    public int deleteByIds(Long[] ids) {
        return ruleMapper.deleteByIds(ids);
    }

    @Override
    @CacheEvict(value = CACHE_NAME, key = "#ruleCode")
    public int updateEnabled(String ruleCode, Integer enabled) {
        return ruleMapper.updateEnabled(ruleCode, enabled);
    }

    @Override
    public List<AlarmRule> selectRulesForRealtime(String deviceModel, String attrKey) {
        AlarmRule query = new AlarmRule();
        query.setEnabled(1);
        query.setUseForRealtime(1);
        query.setDeviceModel(deviceModel);
        query.setAttrKey(attrKey);

        List<AlarmRule> list = ruleMapper.selectForRealtime(query);
        if (CollectionUtils.isNotEmpty(list)) {
            list.forEach(this::parseTargetScope);
        }
        return list;
    }

    @Override
    public List<AlarmRule> selectRulesForInspection(String deviceModel) {
        AlarmRule query = new AlarmRule();
        query.setEnabled(1);
        query.setUseForInspection(1);
        query.setDeviceModel(deviceModel);

        List<AlarmRule> list = ruleMapper.selectForInspection(query);
        if (CollectionUtils.isNotEmpty(list)) {
            list.forEach(this::parseTargetScope);
        }
        return list;
    }

    @Override
    public List<AlarmRule> selectByGroupCode(String groupCode) {
        List<AlarmRule> list = ruleMapper.selectByGroupCode(groupCode);
        if (CollectionUtils.isNotEmpty(list)) {
            list.forEach(this::parseTargetScope);
        }
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AlarmRule copyRule(String sourceRuleCode, String newRuleName) {
        AlarmRule source = selectByRuleCode(sourceRuleCode);
        if (source == null) {
            throw new RuntimeException("源规则不存在: " + sourceRuleCode);
        }

        AlarmRule newRule = new AlarmRule();
        BeanUtils.copyProperties(source, newRule);

        // 重置关键字段
        newRule.setId(null);
        newRule.setRuleCode("RULE_" + Seq.getId());
        newRule.setRuleName(newRuleName);
        newRule.setCreateTime(null);
        newRule.setUpdateTime(null);

        insert(newRule);
        return newRule;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = CACHE_NAME, allEntries = true)
    public int batchUpdateEnabled(List<String> ruleCodes, Integer enabled) {
        if (CollectionUtils.isEmpty(ruleCodes)) {
            return 0;
        }
        return ruleMapper.batchUpdateEnabled(ruleCodes, enabled);
    }

    /**
     * 解析目标范围JSON
     */
    private void parseTargetScope(AlarmRule rule) {
        if (rule == null) {
            return;
        }
        if (StringUtils.isNotBlank(rule.getTargetScope())) {
            try {
                rule.setTargetScopeList(JSON.parseArray(rule.getTargetScope(), String.class));
            } catch (Exception e) {
                log.warn("解析目标范围失败: {}", rule.getTargetScope());
                rule.setTargetScopeList(new ArrayList<>());
            }
        } else {
            rule.setTargetScopeList(new ArrayList<>());
        }
    }
}