package com.ruoyi.rocketmq.service.impl;

import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.rocketmq.domain.RmInitialMonitorItem;
import com.ruoyi.rocketmq.domain.RmMonitorTemplate;
import com.ruoyi.rocketmq.domain.RmTemplateLinux;
import com.ruoyi.rocketmq.domain.RmTemplateSwitch;
import com.ruoyi.rocketmq.domain.vo.RmMonitorTemplateVo;
import com.ruoyi.rocketmq.mapper.RmInitialMonitorItemMapper;
import com.ruoyi.rocketmq.mapper.RmMonitorTemplateMapper;
import com.ruoyi.rocketmq.mapper.RmTemplateLinuxMapper;
import com.ruoyi.rocketmq.mapper.RmTemplateSwitchMapper;
import com.ruoyi.rocketmq.service.IRmMonitorTemplateService;
import com.ruoyi.rocketmq.utils.DataProcessUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;
/**
 * 监控模板Service业务层处理
 * 
 * @author gyt
 * @date 2025-09-09
 */
@Service
public class RmMonitorTemplateServiceImpl implements IRmMonitorTemplateService 
{
    @Autowired
    private RmMonitorTemplateMapper rmMonitorTemplateMapper;
    @Autowired
    private RmTemplateLinuxMapper rmTemplateLinuxMapper;
    @Autowired
    private RmTemplateSwitchMapper rmTemplateSwitchMapper;
    @Autowired
    private RmInitialMonitorItemMapper rmInitialMonitorItemMapper;
    @Autowired
    private DataProcessUtil dataProcessUtil;
    /**
     * 查询监控模板
     * 
     * @param id 监控模板主键
     * @return 监控模板
     */
    @Override
    public RmMonitorTemplate selectRmMonitorTemplateById(Long id)
    {
        return rmMonitorTemplateMapper.selectRmMonitorTemplateById(id);
    }

    /**
     * 查询监控模板列表
     * 
     * @param rmMonitorTemplate 监控模板
     * @return 监控模板
     */
    @Override
    public List<RmMonitorTemplate> selectRmMonitorTemplateList(RmMonitorTemplate rmMonitorTemplate)
    {
        return rmMonitorTemplateMapper.selectRmMonitorTemplateList(rmMonitorTemplate);
    }

    /**
     * 新增监控模板
     * 
     * @param rmMonitorTemplate 监控模板
     * @return 结果
     */
    @Override
    public int insertRmMonitorTemplate(RmMonitorTemplate rmMonitorTemplate)
    {
        rmMonitorTemplate.setCreateTime(DateUtils.getNowDate());
        return rmMonitorTemplateMapper.insertRmMonitorTemplate(rmMonitorTemplate);
    }

    /**
     * 修改监控模板
     * 
     * @param rmMonitorTemplateVo 监控模板
     * @return 结果
     */
    @Override
    public int updateRmMonitorTemplate(RmMonitorTemplateVo rmMonitorTemplateVo)
    {
        RmMonitorTemplate rmMonitorTemplate = new RmMonitorTemplate();
        BeanUtils.copyProperties(rmMonitorTemplateVo, rmMonitorTemplate);
        rmMonitorTemplate.setUpdateTime(DateUtils.getNowDate());
        rmMonitorTemplateMapper.updateRmMonitorTemplate(rmMonitorTemplate);
        Long templateId = rmMonitorTemplate.getId();
        // 检查监控项是否有变动
        boolean hasMonitorChanges = checkMonitorChanges(rmMonitorTemplateVo, templateId);

        if (!hasMonitorChanges) {
            // 如果没有变动，直接返回
            return 1;
        }
        // 先删除旧的监控项
        deleteExistingMonitorItems(templateId, rmMonitorTemplateVo.getResourceType());
        // linux系统信息
        if ("linux".equals(rmMonitorTemplateVo.getResourceType())) {
            processLinuxItems(rmMonitorTemplateVo, templateId);
        }
        // 华为交换机信息
        else if ("switch".equals(rmMonitorTemplateVo.getResourceType())) {
            processSwitchItems(rmMonitorTemplateVo, templateId);
        }
        return 1;
    }
    /**
     * 批量删除监控模板
     * 
     * @param ids 需要删除的监控模板主键
     * @return 结果
     */
    @Override
    public int deleteRmMonitorTemplateByIds(Long[] ids)
    {
        return rmMonitorTemplateMapper.deleteRmMonitorTemplateByIds(ids);
    }

    /**
     * 删除监控模板信息
     * 
     * @param id 监控模板主键
     * @return 结果
     */
    @Override
    public int deleteRmMonitorTemplateById(Long id)
    {
        return rmMonitorTemplateMapper.deleteRmMonitorTemplateById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addRmMonitorTemplate(RmMonitorTemplateVo rmMonitorTemplateVo) {
        RmMonitorTemplate rmMonitorTemplate = new RmMonitorTemplate();
        BeanUtils.copyProperties(rmMonitorTemplateVo, rmMonitorTemplate);
        rmMonitorTemplateMapper.insertRmMonitorTemplate(rmMonitorTemplate);
        Long templateId = rmMonitorTemplate.getId();

        // linux系统信息
        if ("linux".equals(rmMonitorTemplateVo.getResourceType())) {
            processLinuxItems(rmMonitorTemplateVo, templateId);
        }
        // 华为交换机信息
        else if ("switch".equals(rmMonitorTemplateVo.getResourceType())) {
            processSwitchItems(rmMonitorTemplateVo, templateId);
        }
        return 1;
    }

    /**
     * 获取监控模板详情
     * @param id
     * @return
     */
    @Override
    public Map<String, Object> getTemplateMsgById(Long id) {
        Map<String, Object> result = new HashMap<>();

        // 1. 获取模板基础信息
        RmMonitorTemplate template = rmMonitorTemplateMapper.selectRmMonitorTemplateById(id);
        if(template.getResourceGroupId() != null){
            template.setResourceGroupName(dataProcessUtil.getResourceGroupNameById(template.getResourceGroupId()));
        }
        result.put("template", template);

        // 2. 处理Linux模板数据
        dataProcessUtil.processLinuxTemplateData(id, result);

        // 3. 处理Switch模板数据
        dataProcessUtil.processSwitchTemplateData(id, result);

        return result;
    }

    @Override
    public List<Map> getAllTemplate() {
        return rmMonitorTemplateMapper.getAllTemplate();
    }

    /**
     * 删除现有的监控项
     */
    private void deleteExistingMonitorItems(Long templateId, String resourceType) {
        if ("linux".equals(resourceType)) {
            rmTemplateLinuxMapper.deleteByTemplateId(templateId);
        } else if ("switch".equals(resourceType)) {
            rmTemplateSwitchMapper.deleteByTemplateId(templateId);
        }
    }
    /**
     * 检查监控项是否有变动
     */
    private boolean checkMonitorChanges(RmMonitorTemplateVo rmMonitorTemplateVo, Long templateId) {
        if (rmMonitorTemplateVo.getMonitorIds() == null || rmMonitorTemplateVo.getMonitorIds().length == 0) {
            return hasExistingMonitorItems(templateId, rmMonitorTemplateVo.getResourceType());
        }
        // 获取现有的监控项ID
        List<Long> existingMonitorIds = new ArrayList<>();
        if ("linux".equals(rmMonitorTemplateVo.getResourceType())) {
            RmTemplateLinux queryParam = new RmTemplateLinux();
            queryParam.setTemplateId(templateId);
            List<RmTemplateLinux> existingItems = rmTemplateLinuxMapper.selectRmTemplateLinuxList(queryParam);
            for (RmTemplateLinux existingItem : existingItems) {
                Long id = existingItem.getId();
                existingMonitorIds.add(id);
            }
            // 这里需要根据实际情况获取监控项ID，可能需要关联查询
        } else if ("switch".equals(rmMonitorTemplateVo.getResourceType())) {
            RmTemplateSwitch queryParam = new RmTemplateSwitch();
            queryParam.setTemplateId(templateId);
            List<RmTemplateSwitch> existingItems = rmTemplateSwitchMapper.selectRmTemplateSwitchList(queryParam);
            List<Long> idList = new ArrayList<>();
            for (RmTemplateSwitch existingItem : existingItems) {
                Long id = existingItem.getId();
                existingMonitorIds.add(id);
            }
        }
        Long[] nowIds = rmMonitorTemplateVo.getMonitorIds();
        if(isEqualIgnoreOrder(existingMonitorIds, nowIds)){
            return false;
        }
        // 简化处理：只要有监控项就认为有变动
        return true;
    }
    /**
     * 检查是否存在现有的监控项
     */
    private boolean hasExistingMonitorItems(Long templateId, String resourceType) {
        int count = 0;
        if ("linux".equals(resourceType)) {
            RmTemplateLinux queryParam = new RmTemplateLinux();
            queryParam.setTemplateId(templateId);
            count = rmTemplateLinuxMapper.selectRmTemplateLinuxList(queryParam).size();
        } else if ("switch".equals(resourceType)) {
            RmTemplateSwitch queryParam = new RmTemplateSwitch();
            queryParam.setTemplateId(templateId);
            count = rmTemplateSwitchMapper.selectRmTemplateSwitchList(queryParam).size();
        }
        return count > 0;
    }
    /**
     * 比较List和数组内容是否一致（忽略顺序）
     */
    private boolean isEqualIgnoreOrder(List<Long> list, Long[] array) {
        if (list == null && array == null) return true;
        if (list == null || array == null) return false;
        if (list.size() != array.length) return false;

        // 使用Set进行快速比较（如果允许重复元素，需要改用频率统计）
        Set<Long> set1 = new HashSet<>(list);
        Set<Long> set2 = new HashSet<>(Arrays.asList(array));

        return set1.equals(set2);
    }
    /**
     * 处理Linux监控项
     */
    private void processLinuxItems(RmMonitorTemplateVo rmMonitorTemplateVo, Long templateId) {
        if (rmMonitorTemplateVo.getMonitorIds() == null || rmMonitorTemplateVo.getMonitorIds().length == 0) {
            // 如果没有监控项，更新计数为0
            updateTemplateCounts(templateId, 0, 0, "linux");
            return;
        }

        // 根据监控信息id查询详细信息
        List<RmInitialMonitorItem> monitorItems = rmInitialMonitorItemMapper.selectRmInitialMonitorItemByIds(rmMonitorTemplateVo.getMonitorIds());

        // 批量准备插入数据
        List<RmTemplateLinux> linuxItems = monitorItems.stream()
                .map(item -> {
                    RmTemplateLinux linuxItem = new RmTemplateLinux();
                    linuxItem.setTemplateId(templateId);
                    linuxItem.setMetricKey(item.getMetricKey());
                    linuxItem.setMetricName(item.getMetricName());
                    linuxItem.setDataType(item.getDataType());
                    linuxItem.setItemType(item.getItemType());
                    return linuxItem;
                })
                .collect(Collectors.toList());

        // 批量插入
        if (!linuxItems.isEmpty()) {
            rmTemplateLinuxMapper.batchInsertRmTemplateLinux(linuxItems);
            int monitorCount = (int) linuxItems.stream().filter(r -> "monitorItem".equals(r.getItemType())).count();
            int autoDiscoverCount = (int) linuxItems.stream().filter(r -> "autoDiscoverItem".equals(r.getItemType())).count();
            updateTemplateCounts(templateId, monitorCount, autoDiscoverCount, "linux");
        }
    }

    /**
     * 处理交换机监控项
     */
    private void processSwitchItems(RmMonitorTemplateVo rmMonitorTemplateVo, Long templateId) {
        if (rmMonitorTemplateVo.getMonitorIds() == null || rmMonitorTemplateVo.getMonitorIds().length == 0) {
            // 如果没有监控项，更新计数为0
            updateTemplateCounts(templateId, 0, 0, "switch");
            return;
        }

        // 根据监控信息id查询详细信息
        List<RmInitialMonitorItem> monitorItems = rmInitialMonitorItemMapper.selectRmInitialMonitorItemByIds(rmMonitorTemplateVo.getMonitorIds());

        // 批量准备插入数据
        List<RmTemplateSwitch> switchItems = monitorItems.stream()
                .map(item -> {
                    RmTemplateSwitch switchItem = new RmTemplateSwitch();
                    switchItem.setTemplateId(templateId);
                    switchItem.setMetricKey(item.getMetricKey());
                    switchItem.setMetricName(item.getMetricName());
                    switchItem.setOid(item.getOid());
                    switchItem.setFilterValue(item.getFilterValue());
                    switchItem.setSwitchDescription(item.getMonitorDescription());
                    switchItem.setDataType(item.getDataType());
                    switchItem.setItemType(item.getItemType());
                    return switchItem;
                })
                .collect(Collectors.toList());

        // 批量插入
        if (!switchItems.isEmpty()) {
            rmTemplateSwitchMapper.batchInsertRmTemplateSwitch(switchItems);
            int monitorCount = (int) switchItems.stream().filter(r -> "monitorItem".equals(r.getItemType())).count();
            int autoDiscoverCount = (int) switchItems.stream().filter(r -> "autoDiscoverItem".equals(r.getItemType())).count();
            updateTemplateCounts(templateId, monitorCount, autoDiscoverCount, "switch");
        }
    }

    /**
     * 更新模板计数信息
     */
    private void updateTemplateCounts(Long templateId, int monitorCount, int autoDiscoverCount, String resourceType) {
        RmMonitorTemplate monitorTemplate = new RmMonitorTemplate();
        monitorTemplate.setId(templateId);
        monitorTemplate.setMonitorItems(String.valueOf(monitorCount));
        monitorTemplate.setDiscoveryRules(String.valueOf(autoDiscoverCount));
        monitorTemplate.setResourcyType(resourceType);
        rmMonitorTemplateMapper.updateRmMonitorTemplate(monitorTemplate);
    }
}
