package com.ruoyi.system.service.impl;

import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.web.page.PageDomain;
import com.ruoyi.system.domain.EpsInitialTrafficData;
import com.ruoyi.system.domain.EpsNodeBandwidth;
import com.ruoyi.system.domain.RmSwitchManagement;
import com.ruoyi.system.mapper.EpsMethodChangeRecordMapper;
import com.ruoyi.system.mapper.EpsNodeBandwidthMapper;
import com.ruoyi.system.mapper.EpsServerRevenueConfigMapper;
import com.ruoyi.system.mapper.RmSwitchManagementMapper;
import com.ruoyi.system.service.EpsInitialTrafficDataService;
import com.ruoyi.system.service.IEpsNodeBandwidthService;
import com.ruoyi.system.util.EchartsDataConverter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.webjars.NotFoundException;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.common.core.utils.PageUtils.startPage;

/**
 * 节点带宽信息Service业务层处理
 * 
 * @author gyt
 * @date 2025-08-12
 */
@Service
@Slf4j
public class EpsNodeBandwidthServiceImpl implements IEpsNodeBandwidthService 
{
    @Autowired
    private EpsNodeBandwidthMapper epsNodeBandwidthMapper;
    @Autowired
    private  EpsInitialTrafficDataService epsInitialTrafficDataService;
    @Autowired
    private EpsServerRevenueConfigMapper epsServerRevenueConfigMapper;
    @Autowired
    private EpsMethodChangeRecordMapper epsMethodChangeRecordMapper;
    @Autowired
    private RmSwitchManagementMapper rmSwitchManagementMapper;

    /**
     * 查询节点带宽信息
     * 
     * @param id 节点带宽信息主键
     * @return 节点带宽信息
     */
    @Override
    public EpsNodeBandwidth selectEpsNodeBandwidthById(Long id)
    {
        return epsNodeBandwidthMapper.selectEpsNodeBandwidthById(id);
    }

    /**
     * 查询节点带宽信息
     *
     * @param epsNodeBandwidth 节点带宽信息
     * @return 节点带宽信息
     */
    @Override
    public PageInfo<EpsInitialTrafficData> relatedData(EpsNodeBandwidth epsNodeBandwidth, String dailyStartTime, String dailyEndTime) {
        // 设置查询条件
        EpsInitialTrafficData queryParams = new EpsInitialTrafficData();
        queryParams.setServiceSn(epsNodeBandwidth.getHardwareSn());
        queryParams.setBusinessId(epsNodeBandwidth.getBusinessId());
        queryParams.setStartTime(dailyStartTime);
        queryParams.setEndTime(dailyEndTime);
        // 获取总数
//        List<EpsInitialTrafficData> totalList =  epsInitialTrafficDataService.query(queryParams);
        // 4. 设置分页参数
//        PageDomain pageDomain = new PageDomain();
//        pageDomain.setPageNum(epsNodeBandwidth.getPageNum());
//        pageDomain.setPageSize(epsNodeBandwidth.getPageSize());
//        startPage(pageDomain);
        List<EpsInitialTrafficData> resultList =  epsInitialTrafficDataService.query(queryParams);
        int pageNum = epsNodeBandwidth.getPageNum();
        int pageSize = epsNodeBandwidth.getPageSize();
        int startIndex = (pageNum - 1) * pageSize;
        int endIndex = Math.min(startIndex + pageSize, resultList.size());
        List<EpsInitialTrafficData> pageData;
        // 如果startIndex超出范围，返回空列表
        if (startIndex >= resultList.size()) {
            pageData = new ArrayList<>();
        } else {
            // 截取当前分页的数据
            pageData = resultList.subList(startIndex, endIndex);
        }
        PageInfo<EpsInitialTrafficData> pageInfo = new PageInfo<>();
        pageInfo.setList(pageData);
        pageInfo.setTotal(resultList.size());
        pageInfo.setPageNum(epsNodeBandwidth.getPageNum());
        pageInfo.setPageSize(epsNodeBandwidth.getPageSize());
        pageInfo.setPages((int) Math.ceil((double) resultList.size() / epsNodeBandwidth.getPageSize()));
        return pageInfo;
    }
    /**
     * 查询节点带宽信息列表
     * 
     * @param epsNodeBandwidth 节点带宽信息
     * @return 节点带宽信息
     */
    @Override
    public List<EpsNodeBandwidth> selectEpsNodeBandwidthList(EpsNodeBandwidth epsNodeBandwidth)
    {
        return epsNodeBandwidthMapper.selectEpsNodeBandwidthList(epsNodeBandwidth);
    }

    /**
     * 新增节点带宽信息
     * 
     * @param epsNodeBandwidth 节点带宽信息
     * @return 结果
     */
    @Override
    public int insertEpsNodeBandwidth(EpsNodeBandwidth epsNodeBandwidth)
    {
        epsNodeBandwidth.setCreateTime(DateUtils.getNowDate());
        return epsNodeBandwidthMapper.insertEpsNodeBandwidth(epsNodeBandwidth);
    }

    /**
     * 修改节点带宽信息
     * 
     * @param epsNodeBandwidth 节点带宽信息
     * @return 结果
     */
    @Override
    public int updateEpsNodeBandwidth(EpsNodeBandwidth epsNodeBandwidth)
    {
        epsNodeBandwidth.setUpdateTime(DateUtils.getNowDate());
        return epsNodeBandwidthMapper.updateEpsNodeBandwidth(epsNodeBandwidth);
    }

    /**
     * 批量删除节点带宽信息
     * 
     * @param ids 需要删除的节点带宽信息主键
     * @return 结果
     */
    @Override
    public int deleteEpsNodeBandwidthByIds(Long[] ids)
    {
        return epsNodeBandwidthMapper.deleteEpsNodeBandwidthByIds(ids);
    }

    /**
     * 删除节点带宽信息信息
     * 
     * @param id 节点带宽信息主键
     * @return 结果
     */
    @Override
    public int deleteEpsNodeBandwidthById(Long id)
    {
        return epsNodeBandwidthMapper.deleteEpsNodeBandwidthById(id);
    }

    /**
     * 计算月均日95值
     *
     * @param epsNodeBandwidth 节点带宽信息
     * @return 结果
     */
    /**
     * 计算月均日95值
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int calculateAvg(EpsNodeBandwidth epsNodeBandwidth) {
        try {
            // 1. 参数验证
            if (epsNodeBandwidth == null) {
                log.warn("参数为空，无法计算月均日95值");
                return 0;
            }
            // 3. 获取计算数据（防止空指针）
            EpsNodeBandwidth calculatedData = epsNodeBandwidthMapper.calculateAvg(epsNodeBandwidth);
            if (calculatedData == null) {
                log.warn("未找到计算数据，clientId: {}", epsNodeBandwidth.getClientId());
                return 0;
            }

            // 4. 安全获取求和值
            BigDecimal sum95Daily = Optional.ofNullable(calculatedData.getBandwidth95Daily()).orElse(BigDecimal.ZERO);
            BigDecimal sumEffectiveBandwidth95Daily = Optional.ofNullable(calculatedData.getEffectiveBandwidth95Daily()).orElse(BigDecimal.ZERO);

            // 5. 计算当月天数
            LocalDate monthTime;
            try {
                String monthStr = epsNodeBandwidth.getMonthTime() == null
                        ? epsNodeBandwidth.getStartTime().substring(0, 7)
                        : epsNodeBandwidth.getMonthTime();

                YearMonth  yearMonth = YearMonth.parse(monthStr);
                monthTime = yearMonth.atDay(1); // 转换为当月第一天
            } catch (Exception e) {
                log.error("月份时间格式错误: {}", epsNodeBandwidth.getMonthTime() == null
                        ? epsNodeBandwidth.getStartTime() : epsNodeBandwidth.getMonthTime(), e);
                return 0;
            }

            int daysInMonth = YearMonth.from(monthTime).lengthOfMonth();
            if (daysInMonth == 0) {
                log.warn("当月天数为0，月份: {}", epsNodeBandwidth.getMonthTime() == null
                        ? epsNodeBandwidth.getStartTime() : epsNodeBandwidth.getMonthTime());
                return 0;
            }

            // 7. 计算平均值
            epsNodeBandwidth.setBandwidthType("4");
            // 2. 验证是否已经存在记录
            List<EpsNodeBandwidth> existingRecords = epsNodeBandwidthMapper.selectEpsNodeBandwidthList(epsNodeBandwidth);
            if(!existingRecords.isEmpty()){
                epsNodeBandwidth.setId(existingRecords.get(0).getId());
                epsNodeBandwidth.setUpdateTime(DateUtils.getNowDate());
            }else{
                epsNodeBandwidth.setCreateTime(DateUtils.parseDate(monthTime));
            }
            // 月均日95值
            BigDecimal avgMonthly = sum95Daily.divide(BigDecimal.valueOf(daysInMonth), 2, RoundingMode.HALF_UP);
            epsNodeBandwidth.setAvgMonthlyBandwidth95(avgMonthly);
            epsNodeBandwidth.setBandwidthResult(avgMonthly);
            // 根据clientId查询交换机名称
            RmSwitchManagement query = new RmSwitchManagement();
            query.setClientId(epsNodeBandwidth.getClientId());
            List<RmSwitchManagement> switchMsgList = rmSwitchManagementMapper.selectRmSwitchManagementList(query);
            if(!switchMsgList.isEmpty()){
                RmSwitchManagement switchManagement = switchMsgList.get(0);
                epsNodeBandwidth.setUplinkSwitch(switchManagement.getSwitchName());
            }
            // 8. 执行插入或更新操作
            return existingRecords.isEmpty() ?
                    epsNodeBandwidthMapper.insertEpsNodeBandwidth(epsNodeBandwidth) :
                    epsNodeBandwidthMapper.updateEpsNodeBandwidth(epsNodeBandwidth);

        } catch (Exception e) {
            log.error("计算月均日95值失败", e);
            throw new RuntimeException("计算月均日95值失败", e);
        }
    }

    @Override
    public PageInfo<EpsNodeBandwidth> getAvgDetailMsg(Long id, Integer pageNum, Integer pageSize, String dailyStartTime, String dailyEndTime) {
        // 1. 根据ID查询服务器信息
        EpsNodeBandwidth epsNodeBandwidth = epsNodeBandwidthMapper.selectEpsNodeBandwidthById(id);
        if (epsNodeBandwidth == null) {
            throw new NotFoundException("未找到ID为" + id + "的服务器信息");
        }
        epsNodeBandwidth.setStartTime(dailyStartTime);
        epsNodeBandwidth.setEndTime(dailyEndTime);
        List<EpsNodeBandwidth> totalList = epsNodeBandwidthMapper.getAvgDetailMsg(epsNodeBandwidth);
        // 4. 设置分页参数
        PageDomain pageDomain = new PageDomain();
        pageDomain.setPageNum(pageNum);
        pageDomain.setPageSize(pageSize);
        startPage(pageDomain);
        List<EpsNodeBandwidth> nodeBandwidthList = epsNodeBandwidthMapper.getAvgDetailMsg(epsNodeBandwidth);
        PageInfo<EpsNodeBandwidth> pageInfo = new PageInfo<>();
        pageInfo.setList(nodeBandwidthList);
        pageInfo.setTotal(totalList.size());
        pageInfo.setPageNum(pageDomain.getPageNum());
        pageInfo.setPageSize(pageDomain.getPageSize());
        pageInfo.setPages((int) Math.ceil((double) totalList.size() / pageDomain.getPageSize()));
        return pageInfo;
    }
    @Override
    public List<Map> graphicalAnalysis(EpsNodeBandwidth epsNodeBandwidth, String bandwidthType, ChronoUnit timeUnit){
        List<Map> mapList = new ArrayList<>();
        // 拿到列表
        List<EpsNodeBandwidth> nodeBandwidthList = epsNodeBandwidthMapper.selectEpsNodeBandwidthList(epsNodeBandwidth);
        Map<String, EpsNodeBandwidth> uniqueNodes = nodeBandwidthList.stream()
                .collect(Collectors.toMap(
                        // Key生成策略：根据条件动态构建复合键
                        item -> generateCompositeKey(item),
                        // Value转换：创建简化对象
                        item -> createSimplifiedNode(item),
                        // 合并策略：保留第一个出现的记录
                        (existing, replacement) -> existing
                ));
        uniqueNodes.values().forEach(node -> {
            Map<String, Object> nodeData = new HashMap<>();

            // 基础信息
            nodeData.put("nodeName", node.getNodeName());
            nodeData.put("businessName", node.getBusinessName());
            nodeData.put("switchName", node.getUplinkSwitch());
            nodeData.put("interfaceName", node.getInterfaceName());

            // 日带宽数据
            nodeData.put("resultData", EchartsDataConverter.convertToLineChart(
                    nodeBandwidthList,
                    bandwidthType,
                    node.getNodeName(),
                    epsNodeBandwidth.getStartTime(),
                    epsNodeBandwidth.getEndTime(),
                    timeUnit
            ));
            mapList.add(nodeData);
        });
        if("2".equals(epsNodeBandwidth.getResourceType())){
            // 按interfaceName 升序（处理 null 值）
            mapList.sort((map1, map2) -> {
                // 按 interfaceName 升序（处理 null 值）
                String interfaceName1 = (String) map1.get("interfaceName");
                String interfaceName2 = (String) map2.get("interfaceName");

                if (interfaceName1 == null && interfaceName2 == null) {
                    return 0; // 两者都为 null，视为相等
                } else if (interfaceName1 == null) {
                    return -1; // null 排在前面（升序）
                } else if (interfaceName2 == null) {
                    return 1; // null 排在前面（升序）
                } else {
                    return interfaceName1.compareTo(interfaceName2); // 正常比较
                }
            });
        }
        return mapList;
    }

    // 动态生成复合键
    private String generateCompositeKey(EpsNodeBandwidth item) {
        if ("2".equals(item.getResourceType()) && "2".equals(item.getInterfaceLinkDeviceType())) {
            // 特殊条件：忽略nodeName和businessName
            return String.join("|",
                    item.getInterfaceName(),
                    item.getUplinkSwitch()
            );
        } else {
            // 默认情况：使用完整字段
            return String.join("|",
                    Objects.toString(item.getNodeName(), ""),
                    Objects.toString(item.getBusinessName(), ""),
                    item.getInterfaceName(),
                    item.getUplinkSwitch()
            );
        }
    }

    // 创建简化节点对象
    private EpsNodeBandwidth createSimplifiedNode(EpsNodeBandwidth source) {
        EpsNodeBandwidth simplified = new EpsNodeBandwidth();
        simplified.setInterfaceName(source.getInterfaceName());
        simplified.setUplinkSwitch(source.getUplinkSwitch());

        // 仅当非特殊条件时复制这些字段
        if (!("2".equals(source.getResourceType()) && "2".equals(source.getInterfaceLinkDeviceType()))) {
            simplified.setNodeName(source.getNodeName());
            simplified.setBusinessName(source.getBusinessName());
        }

        return simplified;
    }
}
