package com.ruoyi.system.service.impl;

import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.domain.AllInterfaceName;
import com.ruoyi.system.domain.EpsInitialTrafficData;
import com.ruoyi.system.domain.EpsMethodChangeRecord;
import com.ruoyi.system.domain.EpsServerRevenueConfig;
import com.ruoyi.system.mapper.AllInterfaceNameMapper;
import com.ruoyi.system.mapper.EpsMethodChangeRecordMapper;
import com.ruoyi.system.mapper.EpsServerRevenueConfigMapper;
import com.ruoyi.system.service.EpsInitialTrafficDataService;
import com.ruoyi.system.service.IEpsServerRevenueConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

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

/**
 * 服务器收益方式配置Service业务层处理
 * 
 * @author gyt
 * @date 2025-08-19
 */
@Service
@Slf4j
public class EpsServerRevenueConfigServiceImpl implements IEpsServerRevenueConfigService 
{
    @Autowired
    private EpsServerRevenueConfigMapper epsServerRevenueConfigMapper;
    @Autowired
    private EpsInitialTrafficDataService epsInitialTrafficDataService;
    @Autowired
    private EpsMethodChangeRecordMapper epsMethodChangeRecordMapper;
    @Autowired
    private AllInterfaceNameMapper allInterfaceNameMapper;

    /**
     * 查询服务器收益方式配置
     * 
     * @param id 服务器收益方式配置主键
     * @return 服务器收益方式配置
     */
    @Override
    public EpsServerRevenueConfig selectEpsServerRevenueConfigById(Long id)
    {
        return epsServerRevenueConfigMapper.selectEpsServerRevenueConfigById(id);
    }

    /**
     * 查询服务器收益方式配置列表
     * 
     * @param epsServerRevenueConfig 服务器收益方式配置
     * @return 服务器收益方式配置
     */
    @Override
    public List<EpsServerRevenueConfig> selectEpsServerRevenueConfigList(EpsServerRevenueConfig epsServerRevenueConfig)
    {
        return epsServerRevenueConfigMapper.selectEpsServerRevenueConfigList(epsServerRevenueConfig);
    }

    /**
     * 新增服务器收益方式配置
     * 
     * @param epsServerRevenueConfig 服务器收益方式配置
     * @return 结果
     */
    @Override
    public int insertEpsServerRevenueConfig(EpsServerRevenueConfig epsServerRevenueConfig)
    {
        epsServerRevenueConfig.setCreateTime(DateUtils.getNowDate());
        return epsServerRevenueConfigMapper.insertEpsServerRevenueConfig(epsServerRevenueConfig);
    }

    /**
     * 修改服务器收益方式配置
     * 
     * @param epsServerRevenueConfig 服务器收益方式配置
     * @return 结果
     */
    @Override
    public int updateEpsServerRevenueConfig(EpsServerRevenueConfig epsServerRevenueConfig)
    {
        epsServerRevenueConfig.setUpdateTime(DateUtils.getNowDate());
        //原来的收益方式
        EpsServerRevenueConfig serverRevenueConfig = epsServerRevenueConfigMapper.selectEpsServerRevenueConfigById(epsServerRevenueConfig.getId());
        String revenueMethod = getMethodName(serverRevenueConfig.getRevenueMethod());
        //现在的收益方式
        String nowRevenueMethod = getMethodName(epsServerRevenueConfig.getRevenueMethod());
        if(serverRevenueConfig.getBusinessCode() != null){
            if(!serverRevenueConfig.getBusinessCode().equals(epsServerRevenueConfig.getBusinessCode())){
                epsServerRevenueConfig.setChanged("1");
            }
        }
        // 修改条数
        int rows = epsServerRevenueConfigMapper.updateEpsServerRevenueConfig(epsServerRevenueConfig);
        if(rows>=0){
            // 添加操作记录
            addRecord(epsServerRevenueConfig);
            // 添加包端数据到相关数据表
            saveServiceTrafficData(epsServerRevenueConfig);
        }
        return rows;
    }
    /**
     * 添加服务器配置操作记录
     */
    private void addRecord(EpsServerRevenueConfig epsServerRevenueConfig) {
        String nowRevenueMethod = getMethodName(epsServerRevenueConfig.getRevenueMethod());
        EpsMethodChangeRecord changeRecord = new EpsMethodChangeRecord();
        // 设置基本信息
        changeRecord.setNodeName(epsServerRevenueConfig.getNodeName());
        changeRecord.setHardwareSn(epsServerRevenueConfig.getHardwareSn());
        changeRecord.setCreateTime(DateUtils.getNowDate());
        changeRecord.setCreatBy(SecurityUtils.getUsername());
        // 修改内容
        String content = "";
        if("流量".equals(nowRevenueMethod)){
            // 修改内容
            content = "收益方式变为【"+nowRevenueMethod+"】,流量网口设置为"+epsServerRevenueConfig.getTrafficPort()+
                    ",业务为"+epsServerRevenueConfig.getBusinessName();
        }
        if("包端".equals(nowRevenueMethod)){
            // 修改内容
            content = "收益方式变为【"+nowRevenueMethod+"】,流量网口设置为"+epsServerRevenueConfig.getTrafficPort()+
                    ",带宽值设置为"+epsServerRevenueConfig.getPackageBandwidth()+"Mbps,"+"业务为"+epsServerRevenueConfig.getBusinessName();
        }
        changeRecord.setChangeContent(content);
        changeRecord.setBusinessCode(epsServerRevenueConfig.getBusinessCode());
        changeRecord.setBusinessName(epsServerRevenueConfig.getBusinessName());
        changeRecord.setRevenueMethod(epsServerRevenueConfig.getRevenueMethod());
        changeRecord.setPackageBandwidth(epsServerRevenueConfig.getPackageBandwidth());
        changeRecord.setTrafficPort(epsServerRevenueConfig.getTrafficPort());
        // 添加操作记录
        epsMethodChangeRecordMapper.insertEpsMethodChangeRecord(changeRecord);
    }

    /**
     * 保存流量信息
     * @param epsServerRevenueConfig
     */
    private void saveServiceTrafficData(EpsServerRevenueConfig epsServerRevenueConfig) {
        // 初始流量数据
        EpsInitialTrafficData epsInitialTrafficData = new EpsInitialTrafficData();
        epsInitialTrafficData.setServiceSn(epsServerRevenueConfig.getHardwareSn());
        epsInitialTrafficData.setBusinessId(epsServerRevenueConfig.getBusinessCode());
        epsInitialTrafficData.setBusinessName(epsServerRevenueConfig.getBusinessName());
        epsInitialTrafficData.setName(epsServerRevenueConfig.getTrafficPort());
        epsInitialTrafficData.setPackageBandwidth(epsServerRevenueConfig.getPackageBandwidth());
        epsInitialTrafficData.setRevenueMethod(epsServerRevenueConfig.getRevenueMethod());
        epsInitialTrafficData.setNodeName(epsServerRevenueConfig.getNodeName());
        epsInitialTrafficData.setStartTime(epsServerRevenueConfig.getCreateTime() + "");
        epsInitialTrafficData.setEndTime(epsServerRevenueConfig.getCreateTime() + "");
        epsInitialTrafficDataService.save(epsInitialTrafficData);

    }

    /**
     * 保存流量信息
     * @param epsServerRevenueConfig
     */
    @Override
    public R<String> autoSaveServiceTrafficData(EpsServerRevenueConfig epsServerRevenueConfig) {
        // 查询初始流量数据
        EpsInitialTrafficData epsInitialTrafficData = new EpsInitialTrafficData();
        epsInitialTrafficData.setStartTime(epsServerRevenueConfig.getStartTime());
        epsInitialTrafficData.setEndTime(epsServerRevenueConfig.getEndTime());
        List<EpsInitialTrafficData> dataList = epsInitialTrafficDataService.getAllTraficMsg(epsInitialTrafficData);
        List<EpsInitialTrafficData> batchList = new ArrayList<>();
        for (EpsInitialTrafficData initialTrafficData : dataList) {
            // 根据clientId查询节点名称
            Map nodeMsg = epsServerRevenueConfigMapper.getNodeMsgBySn(initialTrafficData.getClientId());
            // 赋值
            if(nodeMsg != null){
                initialTrafficData.setServiceSn(getNullableString(nodeMsg, "hardwareSn"));
                initialTrafficData.setNodeName(getNullableString(nodeMsg, "resourceName"));
                initialTrafficData.setRevenueMethod(getNullableString(nodeMsg, "revenueMethod"));
                initialTrafficData.setBusinessId(getNullableString(nodeMsg, "businessCode"));
                initialTrafficData.setBusinessName(getNullableString(nodeMsg, "businessName"));
                if("2".equals(nodeMsg.get("revenueMethod") + "")
                        && nodeMsg.containsKey("packageBandwidth")){
                    Object bandwidth = nodeMsg.get("packageBandwidth");
                    if (bandwidth instanceof BigDecimal) {
                        initialTrafficData.setPackageBandwidth((BigDecimal) bandwidth);
                    }
                }
            }
            // id自增
            initialTrafficData.setId(null);
            batchList.add(initialTrafficData);
        }
        epsInitialTrafficData.setDataList(batchList);
        // 流量相关数据入库
        try {
            epsInitialTrafficDataService.saveBatch(epsInitialTrafficData);
            log.info("流量数据批量入库成功，数据量：{}", batchList.size());
            // 接口名称保存
            processInterfaceNames(batchList);
            return R.ok("数据保存成功");
        } catch (Exception e) {
            log.error("流量数据入库失败，数据量：{}，错误原因：{}",
                    batchList.size(), e.getMessage(), e);
            return R.fail("数据保存失败：" + e.getMessage());
        }
    }
    /**
     * 当前在线服务器的流量相关的业务数
     * @return
     */
    @Override
    public Integer countBusinessByTraffic() {
        return epsServerRevenueConfigMapper.countBusinessByTraffic();
    }
    /**
     * 当日业务的在线设备数量统计TOP5
     * @return
     */
    @Override
    public List<Map> countDeviceNumTop5() {
        return epsServerRevenueConfigMapper.countDeviceNumTop5();
    }

    private static String getNullableString(Map<String, Object> map, String key) {
        Object value = map.get(key);
        return value != null ? value.toString() : null;
    }
    private String getCompositeKey(String clientId, String interfaceName) {
        return clientId + "|" + interfaceName;
    }
    /**
     * 批量处理接口名称
     */
    private void processInterfaceNames(List<EpsInitialTrafficData> trafficDataList) {
        // 分类处理：新增列表 vs 更新列表
        List<AllInterfaceName> namesToInsert = new ArrayList<>();
        List<AllInterfaceName> namesToUpdate = new ArrayList<>();

        // 用于去重的临时集合，防止同一批数据中的重复
        Set<String> processedKeys = new HashSet<>();

        trafficDataList.forEach(data -> {
            String name = data.getName();
            String ip = data.getMac();
            String clientId = data.getClientId();
            if (StringUtils.isBlank(name) || StringUtils.isBlank(ip) || StringUtils.isBlank(clientId)) {
                return;
            }

            // 生成唯一键，防止同一批数据中的重复处理
            String uniqueKey = name + "|" + clientId + "|" + ip;
            if (processedKeys.contains(uniqueKey)) {
                return;
            }
            processedKeys.add(uniqueKey);

            // 构造新记录
            AllInterfaceName newRecord = new AllInterfaceName();
            newRecord.setInterfaceName(name);
            newRecord.setClientId(data.getClientId());
            newRecord.setResourceType("1");
            newRecord.setDeviceSn(data.getServiceSn());
            newRecord.setNodeName(data.getNodeName());
            newRecord.setBusinessCode(data.getBusinessId());
            newRecord.setBusinessName(data.getBusinessName());
            newRecord.setServerIp(data.getMac());

            List<AllInterfaceName> existingNames = allInterfaceNameMapper.selectByNames(newRecord);

            if (!existingNames.isEmpty()) {
                for (AllInterfaceName existingName : existingNames) {
                    if (isRecordChanged(existingName, newRecord)) {
                        newRecord.setId(existingName.getId());
                        newRecord.setUpdateTime(DateUtils.getNowDate());

                        // 检查是否已经存在于更新列表中
                        boolean alreadyInUpdateList = namesToUpdate.stream()
                                .anyMatch(item -> item.getId() != null && item.getId().equals(existingName.getId()));
                        if (!alreadyInUpdateList) {
                            namesToUpdate.add(newRecord);
                        }
                    }
                }
            } else {
                newRecord.setCreateTime(DateUtils.getNowDate());
                newRecord.setUpdateTime(DateUtils.getNowDate());

                // 检查namesToInsert中是否已有相同记录
                boolean alreadyInInsertList = namesToInsert.stream()
                        .anyMatch(item -> item.getInterfaceName().equals(name)
                                && item.getClientId().equals(clientId)
                                && item.getServerIp().equals(ip));

                if (!alreadyInInsertList) {
                    namesToInsert.add(newRecord);
                }
            }
        });

        // 批量操作数据库
        if (!namesToInsert.isEmpty()) {
            try {
                allInterfaceNameMapper.batchInsert(namesToInsert);
                log.info("新增接口名称数量：{}", namesToInsert.size());
            } catch (DuplicateKeyException e) {
                // 如果批量插入出现重复，转为逐条插入（带异常处理）
                log.warn("批量插入出现重复，转为逐条处理");
                namesToInsert.forEach(record -> {
                    try {
                        allInterfaceNameMapper.insertAllInterfaceName(record);
                    } catch (DuplicateKeyException ex) {
                        // 重复记录转为更新
                        AllInterfaceName query = new AllInterfaceName();
                        query.setInterfaceName(record.getInterfaceName());
                        query.setClientId(record.getClientId());
                        query.setServerIp(record.getServerIp());

                        List<AllInterfaceName> existing = allInterfaceNameMapper.selectByNames(query);
                        if (!existing.isEmpty()) {
                            record.setId(existing.get(0).getId());
                            allInterfaceNameMapper.updateAllInterfaceName(record);
                        }
                    }
                });
            }
        }

        if (!namesToUpdate.isEmpty()) {
            allInterfaceNameMapper.batchUpdate(namesToUpdate);
            log.info("更新接口名称数量：{}", namesToUpdate.size());
        }
    }

    // 辅助方法：检查记录是否有变化
    private boolean isRecordChanged(AllInterfaceName oldRecord, AllInterfaceName newRecord) {
        return !Objects.equals(oldRecord.getDeviceSn(), newRecord.getDeviceSn()) ||
                !Objects.equals(oldRecord.getNodeName(), newRecord.getNodeName()) ||
                !Objects.equals(oldRecord.getBusinessCode(), newRecord.getBusinessCode()) ||
                !Objects.equals(oldRecord.getBusinessName(), newRecord.getBusinessName()) ||
                !Objects.equals(oldRecord.getServerIp(), newRecord.getServerIp());
    }
    /**
     * 批量删除服务器收益方式配置
     * 
     * @param ids 需要删除的服务器收益方式配置主键
     * @return 结果
     */
    @Override
    public int deleteEpsServerRevenueConfigByIds(Long[] ids)
    {
        return epsServerRevenueConfigMapper.deleteEpsServerRevenueConfigByIds(ids);
    }

    /**
     * 删除服务器收益方式配置信息
     * 
     * @param id 服务器收益方式配置主键
     * @return 结果
     */
    @Override
    public int deleteEpsServerRevenueConfigById(Long id)
    {
        return epsServerRevenueConfigMapper.deleteEpsServerRevenueConfigById(id);
    }
    /**
     * 把收益方式转化为文字
     * @param method
     * @return
     */
    public String getMethodName(String method){
        String revenueMethod = "";
        if("1".equals(method)){
            revenueMethod = "流量";
        }
        if("2".equals(method)){
            revenueMethod = "包端";
        }
        return revenueMethod;
    }

}
