package com.tongran.system.service.impl;

import com.tongran.common.core.utils.DateUtils;
import com.tongran.system.domain.*;
import com.tongran.system.mapper.RmMonitorConfigDetailsMapper;
import com.tongran.system.mapper.RmMonitorConfigMapper;
import com.tongran.system.mapper.RmResourceRegistrationMapper;
import com.tongran.system.service.EpsInitialTrafficDataService;
import com.tongran.system.service.IInitialSwitchInfoDetailsService;
import com.tongran.system.service.IRmMonitorConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 监控配置Service业务层处理
 * 
 * @author tongran
 * @date 2025-11-12
 */
@Service
@Slf4j
public class RmMonitorConfigServiceImpl implements IRmMonitorConfigService 
{
    @Autowired
    private RmMonitorConfigMapper rmMonitorConfigMapper;
    @Autowired
    private RmMonitorConfigDetailsMapper rmMonitorConfigDetailsMapper;
    @Autowired
    private EpsInitialTrafficDataService epsInitialTrafficDataService;
    @Autowired
    private IInitialSwitchInfoDetailsService initialSwitchInfoDetailsService;
    @Autowired
    private RmResourceRegistrationMapper rmResourceRegistrationMapper;
    @Autowired
    @Lazy
    private IRmMonitorConfigService self;

    /**
     * 查询监控配置
     * 
     * @param id 监控配置主键
     * @return 监控配置
     */
    @Override
    public RmMonitorConfig selectRmMonitorConfigById(Long id)
    {
        RmMonitorConfig rmMonitorConfig = rmMonitorConfigMapper.selectRmMonitorConfigById(id);
        return rmMonitorConfig;
    }

    /**
     * 查询监控配置列表
     * 
     * @param rmMonitorConfig 监控配置
     * @return 监控配置
     */
    @Override
    public List<RmMonitorConfig> selectRmMonitorConfigList(RmMonitorConfig rmMonitorConfig)
    {
        List<RmMonitorConfig> list = rmMonitorConfigMapper.selectRmMonitorConfigList(rmMonitorConfig);
        return list;
    }

    /**
     * 新增监控配置
     * 
     * @param rmMonitorConfig 监控配置
     * @return 结果
     */
    @Override
    public int insertRmMonitorConfig(RmMonitorConfig rmMonitorConfig)
    {
        rmMonitorConfig.setCreateTime(DateUtils.getNowDate());
        rmMonitorConfigMapper.insertRmMonitorConfig(rmMonitorConfig);
        // 异步触发流量汇总
        self.asyncAfterInsert(rmMonitorConfig.getId());
        return 1;
    }
    @Async
    @Override
    public void asyncAfterInsert(Long monitorConfigId) {
        try {
            log.info("开始异步处理监控配置 {} 的流量汇总", monitorConfigId);
            sumTrafficMyMonitorConfig(monitorConfigId);
            log.info("监控配置 {} 流量汇总完成", monitorConfigId);
        } catch (Exception e) {
            log.error("监控配置 {} 流量汇总异常", monitorConfigId, e);
        }
    }

    /**
     * 修改监控配置
     * 
     * @param rmMonitorConfig 监控配置
     * @return 结果
     */
    @Override
    public int updateRmMonitorConfig(RmMonitorConfig rmMonitorConfig)
    {
        rmMonitorConfig.setUpdateTime(DateUtils.getNowDate());
        return rmMonitorConfigMapper.updateRmMonitorConfig(rmMonitorConfig);
    }

    /**
     * 批量删除监控配置
     * 
     * @param ids 需要删除的监控配置主键
     * @return 结果
     */
    @Override
    public int deleteRmMonitorConfigByIds(Long[] ids)
    {
        int configRows = rmMonitorConfigMapper.deleteRmMonitorConfigByIds(ids);
        // 删除详情
        rmMonitorConfigDetailsMapper.deleteRmMonitorConfigDetailsByMonitorIds(ids);
        return configRows;
    }

    /**
     * 删除监控配置信息
     * 
     * @param id 监控配置主键
     * @return 结果
     */
    @Override
    public int deleteRmMonitorConfigById(Long id)
    {
        return rmMonitorConfigMapper.deleteRmMonitorConfigById(id);
    }

    /**
     * 配置好的数据求和
     */
    @Override
    public void sumTrafficMyMonitorConfig(Long id) {
        List<RmMonitorConfig> rmMonitorConfigList = new ArrayList<>();
        if(id != null){
            RmMonitorConfig rmMonitorConfig = rmMonitorConfigMapper.selectRmMonitorConfigById(id);
            rmMonitorConfigList.add(rmMonitorConfig);
        }else{
            // 查询所有配置
            rmMonitorConfigList = rmMonitorConfigMapper.selectRmMonitorConfigList(new RmMonitorConfig());
        }
        if (rmMonitorConfigList == null || rmMonitorConfigList.isEmpty()) {
            return;
        }
        for (RmMonitorConfig rmMonitorConfig : rmMonitorConfigList) {
            // 判断资源类型
            if("1".equals(rmMonitorConfig.getResourceType()) || "3".equals(rmMonitorConfig.getResourceType())){
                if("3".equals(rmMonitorConfig.getResourceType())){
                    if(rmMonitorConfig.getBusinessName() == null){
                        log.warn("不存在业务");
                        continue;
                    }
                    // 根据业务代码查询服务器clientId
                    RmResourceRegistration queryRegist = new RmResourceRegistration();
                    queryRegist.setBusinessName(rmMonitorConfig.getBusinessName());
                    List<RmResourceRegistration> registrationList = rmResourceRegistrationMapper.getRegistrationTableInfoList(queryRegist);
                    StringBuilder clientIds = new StringBuilder();
                    if (registrationList != null && !registrationList.isEmpty()) {
                        for (RmResourceRegistration registration : registrationList) {
                            if (registration.getClientId() != null) {
                                if (clientIds.length() > 0) {
                                    clientIds.append("\n");
                                }
                                clientIds.append(registration.getClientId());
                            }
                        }
                    }
                    rmMonitorConfig.setDeployDevice(clientIds.toString());
                }
                List<EpsInitialTrafficData> serverTrafficList = epsInitialTrafficDataService.getServerTrafficByMonitorView(rmMonitorConfig);
                if(serverTrafficList == null || serverTrafficList.isEmpty()){
                    log.warn("该监控项暂无数据");
                    continue;
                }
                RmMonitorConfigDetails configDetailsQuery = new RmMonitorConfigDetails();
                configDetailsQuery.setMonitorId(rmMonitorConfig.getId());
                // 查询该数据是否存在
                List<RmMonitorConfigDetails> exitsList = rmMonitorConfigDetailsMapper.selectRmMonitorConfigDetailsList(configDetailsQuery);
                // 将已存在记录的时间转换为Set便于快速查找
                Set<Date> existingTimeSet = exitsList.stream()
                        .map(RmMonitorConfigDetails::getCreateTime)
                        .collect(Collectors.toSet());
                // 批量准备插入数据
                List<RmMonitorConfigDetails> batchInsertList = new ArrayList<>();
                // 计算结果落入临时表
                for (EpsInitialTrafficData epsInitialTrafficData : serverTrafficList) {
                    // 使用Set快速判断是否存在，替代数据库查询
                    if (!existingTimeSet.contains(epsInitialTrafficData.getCreateTime())) {
                        RmMonitorConfigDetails configDetails = new RmMonitorConfigDetails();
                        configDetails.setMonitorId(rmMonitorConfig.getId());
                        configDetails.setCreateTime(epsInitialTrafficData.getCreateTime());
                        configDetails.setInSpeed(new BigDecimal(epsInitialTrafficData.getInSpeed() == null ? "0" : epsInitialTrafficData.getInSpeed()));
                        configDetails.setOutSpeed(new BigDecimal(epsInitialTrafficData.getOutSpeed() == null ? "0" : epsInitialTrafficData.getOutSpeed()));
                        configDetails.setDeployDevice(rmMonitorConfig.getDeployDevice());
                        batchInsertList.add(configDetails);
                    }
                }
                // 批量插入
                if(!batchInsertList.isEmpty()){
                    batchInsertInChunks(batchInsertList, rmMonitorConfig.getId());
                }
            }else{
                List<InitialSwitchInfoDetails> switchInfoDetailsList = initialSwitchInfoDetailsService.getMonitorViewDetails(rmMonitorConfig);
                if(switchInfoDetailsList == null || switchInfoDetailsList.isEmpty()){
                    log.warn("该监控项暂无数据");
                    continue;
                }
                RmMonitorConfigDetails configDetailsQuery = new RmMonitorConfigDetails();
                configDetailsQuery.setMonitorId(rmMonitorConfig.getId());
                // 查询该数据是否存在
                List<RmMonitorConfigDetails> exitsList = rmMonitorConfigDetailsMapper.selectRmMonitorConfigDetailsList(configDetailsQuery);
                // 将已存在记录的时间转换为Set便于快速查找
                Set<Date> existingTimeSet = exitsList.stream()
                        .map(RmMonitorConfigDetails::getCreateTime)
                        .collect(Collectors.toSet());
                // 批量准备插入数据
                List<RmMonitorConfigDetails> batchInsertList = new ArrayList<>();
                for (InitialSwitchInfoDetails initialSwitchInfoDetails : switchInfoDetailsList) {
                    // 使用Set快速判断是否存在，替代数据库查询
                    if (!existingTimeSet.contains(initialSwitchInfoDetails.getCreateTime())) {
                        RmMonitorConfigDetails configDetails = new RmMonitorConfigDetails();
                        configDetails.setMonitorId(rmMonitorConfig.getId());
                        configDetails.setCreateTime(initialSwitchInfoDetails.getCreateTime());
                        configDetails.setInSpeed(initialSwitchInfoDetails.getInSpeed());
                        configDetails.setOutSpeed(initialSwitchInfoDetails.getOutSpeed());
                        configDetails.setDeployDevice(rmMonitorConfig.getDeployDevice());
                        batchInsertList.add(configDetails);
                    }
                    // 批量插入
                    if(!batchInsertList.isEmpty()){
                        batchInsertInChunks(batchInsertList, rmMonitorConfig.getId());
                    }
                }
            }
        }
    }
    private void batchInsertInChunks(List<RmMonitorConfigDetails> batchInsertList, Long monitorId) {
        if (batchInsertList == null || batchInsertList.isEmpty()) {
            return;
        }

        int batchSize = 288; // 可配置化
        int totalSize = batchInsertList.size();

        for (int i = 0; i < totalSize; i += batchSize) {
            int end = Math.min(i + batchSize, totalSize);
            List<RmMonitorConfigDetails> subList = batchInsertList.subList(i, end);

            try {
                rmMonitorConfigDetailsMapper.batchInsertRmMonitorConfigDetails(subList);
                log.debug("监控配置 {}: 成功插入 {} 条记录，进度: {}/{}",
                        monitorId, subList.size(), i/batchSize + 1,
                        (totalSize + batchSize - 1) / batchSize);
            } catch (Exception e) {
                log.error("监控配置 {} 批次插入失败，范围: {}-{}", monitorId, i, end, e);
            }
        }
    }

}
