package com.ruoyi.rocketmq.service.impl;

import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.EchartsDataUtils;
import com.ruoyi.common.core.utils.SpeedUtils;
import com.ruoyi.rocketmq.domain.InitialBandwidthTraffic;
import com.ruoyi.rocketmq.mapper.InitialBandwidthTrafficMapper;
import com.ruoyi.rocketmq.service.IInitialBandwidthTrafficService;
import com.ruoyi.rocketmq.utils.TableRouterUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 初始带宽流量Service业务层处理
 * 
 * @author gyt
 * @date 2025-08-20
 */
@Service
@Slf4j
public class InitialBandwidthTrafficServiceImpl implements IInitialBandwidthTrafficService 
{
    @Autowired
    private InitialBandwidthTrafficMapper initialBandwidthTrafficMapper;

    /**
     * 查询初始带宽流量
     * 
     * @param id 初始带宽流量主键
     * @return 初始带宽流量
     */
    @Override
    public InitialBandwidthTraffic selectInitialBandwidthTrafficById(Long id)
    {
        return initialBandwidthTrafficMapper.selectInitialBandwidthTrafficById(id);
    }

    /**
     * 查询初始带宽流量列表
     * 
     * @param initialBandwidthTraffic 初始带宽流量
     * @return 初始带宽流量
     */
    @Override
    public List<InitialBandwidthTraffic> selectInitialBandwidthTrafficList(InitialBandwidthTraffic initialBandwidthTraffic)
    {
        return initialBandwidthTrafficMapper.selectInitialBandwidthTrafficList(initialBandwidthTraffic);
    }

    /**
     * 新增初始带宽流量
     * 
     * @param initialBandwidthTraffic 初始带宽流量
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertInitialBandwidthTraffic(InitialBandwidthTraffic initialBandwidthTraffic)
    {
        initialBandwidthTraffic.setCreateTime(DateUtils.getNowDate());
        return initialBandwidthTrafficMapper.insertInitialBandwidthTraffic(initialBandwidthTraffic);
    }

    /**
     * 修改初始带宽流量
     * 
     * @param initialBandwidthTraffic 初始带宽流量
     * @return 结果
     */
    @Override
    public int updateInitialBandwidthTraffic(InitialBandwidthTraffic initialBandwidthTraffic)
    {
        initialBandwidthTraffic.setUpdateTime(DateUtils.getNowDate());
        return initialBandwidthTrafficMapper.updateInitialBandwidthTraffic(initialBandwidthTraffic);
    }

    /**
     * 批量删除初始带宽流量
     * 
     * @param ids 需要删除的初始带宽流量主键
     * @return 结果
     */
    @Override
    public int deleteInitialBandwidthTrafficByIds(Long[] ids)
    {
        return initialBandwidthTrafficMapper.deleteInitialBandwidthTrafficByIds(ids);
    }

    /**
     * 删除初始带宽流量信息
     * 
     * @param id 初始带宽流量主键
     * @return 结果
     */
    @Override
    public int deleteInitialBandwidthTrafficById(Long id)
    {
        return initialBandwidthTrafficMapper.deleteInitialBandwidthTrafficById(id);
    }

    /**
     * 保存单条数据到对应分表
     * @param data 流量数据
     */
    @Override
    @Transactional
    public void save(InitialBandwidthTraffic data) {
        if (data.getCreateTime() == null) {
            data.setCreateTime(DateUtils.getNowDate());
        }
        Date date = data.getCreateTime();
        LocalDateTime createTime = date.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
        data.setTableName(TableRouterUtil.getTableName(createTime));
        initialBandwidthTrafficMapper.insert(data);
    }
    /**
     * 保存多条数据到对应分表
     * @param initialBandwidthTraffic 流量数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public void batchInsert(InitialBandwidthTraffic initialBandwidthTraffic) {
        if (initialBandwidthTraffic == null) {
            return;
        }
        List<InitialBandwidthTraffic> dataList = initialBandwidthTraffic.getList();
        if (dataList.isEmpty()){
            return;
        }
        // 按表名分组批量插入
        Map<String, List<InitialBandwidthTraffic>> groupedData = dataList.stream()
                .map(data -> {
                    try {
                        InitialBandwidthTraffic processed = new InitialBandwidthTraffic();
                        BeanUtils.copyProperties(data,processed);
                        if (data.getCreateTime() == null) {
                            data.setCreateTime(DateUtils.getNowDate());
                        }
                        LocalDateTime createTime = data.getCreateTime().toInstant()
                                .atZone(ZoneId.systemDefault())
                                .toLocalDateTime();
                        processed.setTableName(TableRouterUtil.getTableName(createTime));
                        return processed;
                    } catch (Exception e){
                        log.error("数据处理失败",e.getMessage());
                        return null;
                    }
                }).collect(Collectors.groupingBy(
                        InitialBandwidthTraffic::getTableName,
                        LinkedHashMap::new, // 保持插入顺序
                        Collectors.toList()));

        groupedData.forEach((tableName, list) -> {
            try {
                InitialBandwidthTraffic data = new InitialBandwidthTraffic();
                BeanUtils.copyProperties(initialBandwidthTraffic,data);
                data.setTableName(tableName);
                data.setList(list);
                initialBandwidthTrafficMapper.batchInsert(data);
            } catch (Exception e) {
                log.error("表{}插入失败", tableName, e);
                throw new RuntimeException("批量插入失败", e);
            }
        });
    }
    /**
     * 网络接口基础信息
     * @param initialBandwidthTraffic
     * @return
     */
    @Override
    public InitialBandwidthTraffic getNetInterfaceDetailsMsg(InitialBandwidthTraffic initialBandwidthTraffic) {
        if (initialBandwidthTraffic.getCreateTime() == null) {
            initialBandwidthTraffic.setCreateTime(DateUtils.getNowDate());
        }
        LocalDateTime createTime = initialBandwidthTraffic.getCreateTime().toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
        initialBandwidthTraffic.setTableName(TableRouterUtil.getTableName(createTime));
        InitialBandwidthTraffic detailsMsg = initialBandwidthTrafficMapper.getNetInterfaceDetailsMsg(initialBandwidthTraffic);
        return detailsMsg;
    }

    /**
     * 分表查询需要的信息
     * @param initialBandwidthTraffic
     * @return
     */
    public List<InitialBandwidthTraffic> getListByTableName(InitialBandwidthTraffic initialBandwidthTraffic){
        // 获取涉及的表名
        Set<String> tableNames = TableRouterUtil.getTableNamesBetween(initialBandwidthTraffic.getStartTime(), initialBandwidthTraffic.getEndTime());
        // 并行查询各表
        List<InitialBandwidthTraffic> list =  tableNames.parallelStream()
                .flatMap(tableName -> {
                    InitialBandwidthTraffic condition = new InitialBandwidthTraffic();
                    condition.setTableName(tableName);
                    condition.setStartTime(initialBandwidthTraffic.getStartTime());
                    condition.setEndTime(initialBandwidthTraffic.getEndTime());
                    condition.setClientId(initialBandwidthTraffic.getClientId());
                    condition.setName(initialBandwidthTraffic.getName());
                    return initialBandwidthTrafficMapper.getNetTrafficList(condition).stream();
                })
                .collect(Collectors.toList());
        return list;
    }
    /**
     * 查询eth0流量信息并封装为多折线ECharts图表数据
     * @param initialBandwidthTraffic
     * @return
     */
    @Override
    public Map<String, Object> netInterfaceTrafficEcharts(InitialBandwidthTraffic initialBandwidthTraffic) {
        // 流量信息
        List<InitialBandwidthTraffic> list = getListByTableName(initialBandwidthTraffic);
        try {
            String unit = SpeedUtils.calculateUnitWithStringTraffic(list, "inSpeed", "outSpeed");
            BigDecimal divisor = SpeedUtils.getDivisor(unit);
            Map<String, Function<InitialBandwidthTraffic, ?>> extractors = new LinkedHashMap<>();
            extractors.put("netInSpeedData", info ->
                    info != null && info.getInSpeed() != null ?
                            new BigDecimal(info.getInSpeed()).divide(divisor, 0, RoundingMode.HALF_UP) :
                            0);

            extractors.put("netOutSpeedData", info ->
                    info != null && info.getOutSpeed() != null ?
                            new BigDecimal(info.getOutSpeed()).divide(divisor, 0, RoundingMode.HALF_UP) :
                            0);
            Map<String, Object> resultMap = EchartsDataUtils.buildEchartsData(list, InitialBandwidthTraffic::getCreateTime, extractors);
            resultMap.put("unit", unit);
            return resultMap;
        } catch (Exception e){
            e.printStackTrace();
        }
        return new HashMap<>();
    }
    // 安全转换方法（处理可能的NumberFormatException）
    private Double safeConvertToKB(String byteValue) {
        try {
            return byteValue == null ? 0.0 : Double.parseDouble(byteValue) / 1024.0;
        } catch (NumberFormatException e) {
            return 0.0; // 或根据业务需求返回null/抛出异常
        }
    }
    /**
     * 查询eth0流量信息丢包数并封装为折线ECharts图表数据
     * @param initialBandwidthTraffic
     * @return
     */
    @Override
    public Map<String, Object> netInterfaceDroppedEcharts(InitialBandwidthTraffic initialBandwidthTraffic) {
        // 流量信息
        List<InitialBandwidthTraffic> list = getListByTableName(initialBandwidthTraffic);
        Map<String, Function<InitialBandwidthTraffic, ?>> extractors = new LinkedHashMap<>();
        extractors.put("inDroppedData", info -> info.getInDropped());
        extractors.put("outDroppedData", info -> info.getOutDropped());

        return EchartsDataUtils.buildEchartsData(list, InitialBandwidthTraffic::getCreateTime, extractors);
    }

}
