package com.tongran.mtragent.service.impl;

import com.tongran.common.core.utils.DateUtils;
import com.tongran.common.core.utils.EchartsDataUtils;
import com.tongran.common.core.utils.TableSubUtil;
import com.tongran.mtragent.domain.RmMtrProbeResult;
import com.tongran.mtragent.mapper.RmMtrProbeResultMapper;
import com.tongran.mtragent.service.IRmMtrProbeResultService;
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.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 网络mtr探测结果Service业务层处理
 * 
 * @author tongran
 * @date 2025-11-20
 */
@Service
@Slf4j
public class RmMtrProbeResultServiceImpl implements IRmMtrProbeResultService 
{
    @Autowired
    private RmMtrProbeResultMapper rmMtrProbeResultMapper;

    private final static String TABLE_PREFIX = "rm_mtr_probe_result";

    /**
     * 查询网络mtr探测结果
     * 
     * @param id 网络mtr探测结果主键
     * @return 网络mtr探测结果
     */
    @Override
    public RmMtrProbeResult selectRmMtrProbeResultById(Long id)
    {
        return rmMtrProbeResultMapper.selectRmMtrProbeResultById(id);
    }

    /**
     * 查询网络mtr探测结果列表
     * 
     * @param rmMtrProbeResult 网络mtr探测结果
     * @return 网络mtr探测结果
     */
    @Override
    public List<RmMtrProbeResult> selectRmMtrProbeResultList(RmMtrProbeResult rmMtrProbeResult)
    {
        return rmMtrProbeResultMapper.selectRmMtrProbeResultList(rmMtrProbeResult);
    }

    /**
     * 新增网络mtr探测结果
     * 
     * @param rmMtrProbeResult 网络mtr探测结果
     * @return 结果
     */
    @Override
    public int insertRmMtrProbeResult(RmMtrProbeResult rmMtrProbeResult)
    {
        Date createTime = rmMtrProbeResult.getCreateTime();
        String tableName = TableSubUtil.getTableName(createTime, TABLE_PREFIX);
        return rmMtrProbeResultMapper.insertRmMtrProbeResult(rmMtrProbeResult);
    }

    /**
     * 修改网络mtr探测结果
     * 
     * @param rmMtrProbeResult 网络mtr探测结果
     * @return 结果
     */
    @Override
    public int updateRmMtrProbeResult(RmMtrProbeResult rmMtrProbeResult)
    {
        rmMtrProbeResult.setUpdateTime(DateUtils.getNowDate());
        return rmMtrProbeResultMapper.updateRmMtrProbeResult(rmMtrProbeResult);
    }

    /**
     * 批量删除网络mtr探测结果
     * 
     * @param ids 需要删除的网络mtr探测结果主键
     * @return 结果
     */
    @Override
    public int deleteRmMtrProbeResultByIds(Long[] ids)
    {
        return rmMtrProbeResultMapper.deleteRmMtrProbeResultByIds(ids);
    }

    /**
     * 删除网络mtr探测结果信息
     * 
     * @param id 网络mtr探测结果主键
     * @return 结果
     */
    @Override
    public int deleteRmMtrProbeResultById(Long id)
    {
        return rmMtrProbeResultMapper.deleteRmMtrProbeResultById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
    public void batchInsertRmMtrProbeResult(RmMtrProbeResult rmMtrProbeResult) {
        if (rmMtrProbeResult == null) {
            return;
        }
        List<RmMtrProbeResult> dataList = rmMtrProbeResult.getList();
        if (dataList == null || dataList.isEmpty()) {
            return;
        }

        // 按表名分组批量插入
        Map<String, List<RmMtrProbeResult>> groupedData = dataList.stream()
                .map(data -> {
                    try {
                        RmMtrProbeResult processed = new RmMtrProbeResult();
                        BeanUtils.copyProperties(data, processed);
                        if (data.getCreateTime() == null) {
                            processed.setCreateTime(new Date());
                        }
                        if(data.getUpdateTime() == null){
                            processed.setUpdateTime(new Date());
                        }
                        processed.setTableName(TableSubUtil.getTableName(data.getCreateTime(), TABLE_PREFIX));
                        return processed;
                    } catch (Exception e) {
                        log.error("RmMtrProbeResult数据处理失败", e);
                        return null;
                    }
                })
                .filter(Objects::nonNull) // 过滤掉处理失败的数据
                .collect(Collectors.groupingBy(
                        RmMtrProbeResult::getTableName,
                        LinkedHashMap::new, // 保持插入顺序
                        Collectors.toList()));

        groupedData.forEach((tableName, list) -> {
            try {
                RmMtrProbeResult batchData = new RmMtrProbeResult();
                BeanUtils.copyProperties(rmMtrProbeResult, batchData);
                batchData.setTableName(tableName);
                batchData.setList(list);
                rmMtrProbeResultMapper.batchInsertRmMtrProbeResult(batchData);
            } catch (Exception e) {
                log.error("表{}插入失败", tableName, e);
                throw new RuntimeException("批量插入失败", e);
            }
        });
    }

    /**
     * 分表查询探测结果
     * @param queryParam
     * @return
     */
    public List<RmMtrProbeResult> getListByTime(RmMtrProbeResult queryParam){
        // 获取涉及的表名
        Set<String> tableNames = TableSubUtil.getExistingTableNamesBetween(
                queryParam.getStartTime(),
                queryParam.getEndTime(),
                TABLE_PREFIX
        );

        // 并行查询各表
        return tableNames.parallelStream()
                .flatMap(tableName -> {
                    RmMtrProbeResult condition = new RmMtrProbeResult();
                    condition.setTableName(tableName);
                    condition.setMtrClientId(queryParam.getMtrClientId());
                    condition.setClientId(queryParam.getClientId());
                    condition.setStartTime(queryParam.getStartTime());
                    condition.setEndTime(queryParam.getEndTime());
                    return rmMtrProbeResultMapper.selectByCondition(condition).stream();
                })
                .collect(Collectors.toList());
    }

    /**
     * 查看丢包率趋势
     * @param rmMtrProbeResult
     * @return
     */
    @Override
    public Map<String, Object> getLossRateByMtrClientId(RmMtrProbeResult rmMtrProbeResult) {
        if(rmMtrProbeResult.getStartTime() == null && rmMtrProbeResult.getEndTime() == null){
            String[] timeRange = DateUtils.getTodayTimeRange();
            rmMtrProbeResult.setStartTime(timeRange[0]);
            rmMtrProbeResult.setEndTime(timeRange[1]);
        }
        List<RmMtrProbeResult> list = getListByTime(rmMtrProbeResult);
        if(list == null){
            list = new ArrayList<>();
        }
        try {
            Map<String, Function<RmMtrProbeResult, ?>> extractors = new LinkedHashMap<>();

            extractors.put("packetLossRate", info ->
                    info != null && info.getPacketLossRate() != null ?
                            info.getPacketLossRate() :
                            0);
            // 每一跳的分析结果
            extractors.put("deployDevice", info ->
                    info != null && info.getHopResult() != null ?
                            info.getHopResult() :
                            null);
            Map<String, Object> resultMap = EchartsDataUtils.buildEchartsDataAutoPadding(
                    list, RmMtrProbeResult::getCreateTime, extractors, rmMtrProbeResult.getStartTime(), rmMtrProbeResult.getEndTime()
            );
            return resultMap;
        } catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}
