package com.usky.ems.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.usky.ems.domain.DmpDevice;
import com.usky.ems.domain.EmsConsPlatformConfig;
import com.usky.ems.domain.TdengineData;
import com.usky.ems.protocol.TcpClient;
import com.usky.ems.service.DmpDeviceService;
import com.usky.ems.service.EmsConsPlatformConfigService;
import com.usky.ems.service.EnergyDataService;
import com.usky.ems.service.TdengineService;
import com.usky.ems.util.XmlBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 能耗数据服务实现类
 *
 * @author system
 * @since 2024-01-01
 */
@Service
public class EnergyDataServiceImpl implements EnergyDataService {

    private static final Logger logger = LoggerFactory.getLogger(EnergyDataServiceImpl.class);


    private final DmpDeviceService dmpDeviceService;
    private final TdengineService tdengineService;
    private final EmsConsPlatformConfigService emsConsPlatformConfigService;

    // TCP客户端连接池（每个网关一个连接）
    private final Map<String, TcpClient> clientPool = new HashMap<>();

    public EnergyDataServiceImpl(DmpDeviceService dmpDeviceService, TdengineService tdengineService, EmsConsPlatformConfigService emsConsPlatformConfigService) {
        this.dmpDeviceService = dmpDeviceService;
        this.tdengineService = tdengineService;
        this.emsConsPlatformConfigService = emsConsPlatformConfigService;
    }

    @Override
    public void sendEnergyData(){
        logger.info("开始执行能耗数据推送任务");

        List<EmsConsPlatformConfig> platformConfigList = emsConsPlatformConfigService.getPlatformConfig();
        if(CollectionUtils.isNotEmpty(platformConfigList)){
            for (EmsConsPlatformConfig platformConfig : platformConfigList) {
                String serverHost = platformConfig.getPlatformIp();
                int serverPort = platformConfig.getPlatformPort();
                String authKey = platformConfig.getPasswd();
                String buildingId = platformConfig.getBuildId();
                Integer tenantId = platformConfig.getTenantId();
                String productCode = platformConfig.getProductCode();


                // 1. 查询网关设备
                List<DmpDevice> gatewayList = dmpDeviceService.getGatewayByDeviceId(tenantId,productCode);
                if (CollectionUtils.isEmpty(gatewayList)) {
                    logger.error("{}产品下不存在网关设备", productCode);
                }
                for (DmpDevice dmpDevice : gatewayList) {
                    String gatewayId = dmpDevice.getDeviceId();
                    try {

                        // 2. 查询网关下的所有电表设备
                        List<DmpDevice> devices = dmpDeviceService.getDevicesByGatewayUuid(dmpDevice.getDeviceUuid());
                        if (devices == null || devices.isEmpty()) {
                            logger.warn("{}网关下没有电表设备", dmpDevice);
                            continue;
                        }

                        // 3. 查询所有设备的最新数据
                        List<String> deviceUuids = new ArrayList<>();
                        for (DmpDevice device : devices) {
                            if(!deviceUuids.contains(device.getDeviceUuid())){
                                deviceUuids.add(device.getDeviceUuid());
                            }

                        }
                        Map<String, TdengineData> dataMap = tdengineService.getLatestDataBatch(deviceUuids);

                        // 4. 构建XML数据
                        String xmlData = buildEnergyDataXml(buildingId, dmpDevice.getDeviceId(), devices, dataMap);

                        // 5. 获取或创建TCP客户端连接
                        TcpClient client = getOrCreateClient(serverHost, serverPort, authKey, buildingId, gatewayId);
                        if (client == null) {
                            logger.error("无法建立TCP连接: {}", gatewayId);
                        }

                        // 6. 发送数据
                        boolean success = client.sendEnergyData(xmlData);

                        if (success) {
                            logger.info("能耗数据推送成功: gatewayId={}, deviceCount={}", gatewayId, devices.size());
                        } else {
                            logger.error("能耗数据推送失败: gatewayId={}", gatewayId);
                        }

                    } catch (Exception e) {
                        logger.error("生成并推送能耗数据异常: gatewayId={}", gatewayId, e);
                    }
                }
            }

        }

        logger.info("能耗数据推送任务执行完成");
    }

    @Override
    public void sendEnergyHeartbeat(){
        logger.debug("开始执行心跳任务");

        List<EmsConsPlatformConfig> platformConfigList = emsConsPlatformConfigService.getPlatformConfig();
        if(CollectionUtils.isNotEmpty(platformConfigList)){
            for (EmsConsPlatformConfig platformConfig : platformConfigList) {
                String serverHost = platformConfig.getPlatformIp();
                int serverPort = platformConfig.getPlatformPort();
                String authKey = platformConfig.getPasswd();
                String buildingId = platformConfig.getBuildId();
                Integer tenantId = platformConfig.getTenantId();
                String productCode = platformConfig.getProductCode();


                // 1. 查询网关设备
                List<DmpDevice> gatewayList = dmpDeviceService.getGatewayByDeviceId(tenantId,productCode);
                if (CollectionUtils.isEmpty(gatewayList)) {
                    logger.error("{}产品下不存在网关设备", productCode);
                }
                for (DmpDevice dmpDevice : gatewayList) {
                    String gatewayId = dmpDevice.getDeviceId();
                    try {
                        // 2. 获取TCP客户端连接
                        TcpClient client = getOrCreateClient(serverHost, serverPort, authKey, buildingId, gatewayId);
                        if (client == null || !client.isConnected() || !client.isAuthenticated()) {
                            logger.warn("网关连接不存在或未认证，跳过心跳: gatewayId={}", gatewayId);
                        }

                        // 3. 发送心跳
                        boolean success = client.sendHeartbeat(buildingId, gatewayId);

                        if (success) {
                            logger.debug("心跳发送成功: gatewayId={}", gatewayId);
                        } else {
                            logger.warn("心跳发送失败: gatewayId={}", gatewayId);
                        }

                    } catch (Exception e) {
                        logger.error("发送心跳异常: gatewayId={}", gatewayId, e);
                    }
                }
            }

        }

        logger.debug("心跳任务执行完成");
    }

    /**
     * 构建能耗数据XML
     */
    private String buildEnergyDataXml(String buildingId, String gatewayId, List<DmpDevice> devices, Map<String, TdengineData> dataMap) {
        String time = XmlBuilder.formatCurrentTime();

        // 计算分项数据（总电量）
        Map<String, Double> energyItems = new HashMap<>();
        double totalEnergy = 0.0;
//        for (TdengineData data : dataMap.values()) {
//            if (data.getTotalActiveEnergyF() != null) {
//                totalEnergy += data.getTotalActiveEnergyF();
//            }
//        }
        energyItems.put("0", totalEnergy);

        // 构建仪表数据
        List<Map<String, Object>> meters = new ArrayList<>();
        for (DmpDevice device : devices) {
            TdengineData data = dataMap.get(device.getDeviceUuid());
            if (data == null) {
                continue;
            }

            Map<String, Object> meter = new HashMap<>();
            meter.put("id", buildingId + "M" + device.getDeviceId().substring(device.getDeviceId().length() - 3));
            meter.put("name", device.getDeviceName());

            List<Map<String, String>> functions = new ArrayList<>();
            
            // 累计正向有功电量
            if (data.getTotalActiveEnergyF() != null) {
                functions.add(createFunction("WPP", String.valueOf(data.getTotalActiveEnergyF()), null));
            }
            
//            // 正向有功功率
//            if (data.getTotalActivePower() != null) {
//                functions.add(createFunction("Ps", String.valueOf(data.getTotalActivePower()), null));
//            }
//
//            // 正向无功功率
//            if (data.getTotalReactiveEnergyF() != null) {
//                functions.add(createFunction("Qs", String.valueOf(data.getTotalReactiveEnergyF()), null));
//            }
//
//            // A相电压
//            if (data.getVoltageA() != null) {
//                functions.add(createFunction("Ua", String.valueOf(data.getVoltageA()), null));
//            }
//
//            // B相电压
//            if (data.getVoltageB() != null) {
//                functions.add(createFunction("Ub", String.valueOf(data.getVoltageB()), null));
//            }
//
//            // C相电压
//            if (data.getVoltageC() != null) {
//                functions.add(createFunction("Uc", String.valueOf(data.getVoltageC()), null));
//            }
            
            // A相电流
            if (data.getCurrentA() != null) {
                functions.add(createFunction("Ia", String.valueOf(data.getCurrentA()), null));
            }
            
            // B相电流
            if (data.getCurrentB() != null) {
                functions.add(createFunction("Ib", String.valueOf(data.getCurrentB()), null));
            }
            
            // C相电流
            if (data.getCurrentC() != null) {
                functions.add(createFunction("Ic", String.valueOf(data.getCurrentC()), null));
            }
            
//            // 功率因数
//            if (data.getTotalPowerFactor() != null) {
//                functions.add(createFunction("PFs", String.valueOf(data.getTotalPowerFactor()), null));
//            }

            meter.put("functions", functions);
            meters.add(meter);
        }

        return XmlBuilder.buildEnergyDataRequest(buildingId, gatewayId, time, energyItems, meters);
    }

    /**
     * 创建function节点数据
     */
    private Map<String, String> createFunction(String id, String value, String error) {
        Map<String, String> function = new HashMap<>();
        function.put("id", id);
        function.put("value", value);
        if (error != null) {
            function.put("error", error);
        }
        return function;
    }

    /**
     * 获取或创建TCP客户端
     */
    private synchronized TcpClient getOrCreateClient(String serverHost, int serverPort, String authKey, String buildingId, String gatewayId) {
        TcpClient client = clientPool.get(gatewayId);
        
        if (client == null || !client.isConnected() || !client.isAuthenticated()) {
            // 创建新连接
            client = new TcpClient(serverHost, serverPort, authKey);
            
            // 建立连接
            if (!client.connect()) {
                return null;
            }
            
            // 身份认证
            if (!client.authenticate(buildingId, gatewayId)) {
                client.close();
                return null;
            }
            
            clientPool.put(gatewayId, client);
        }
        
        return client;
    }
}
