package com.usky.cdi.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.alibaba.nacos.shaded.com.google.gson.GsonBuilder;
import com.alibaba.nacos.shaded.com.google.gson.LongSerializationPolicy;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.usky.cdi.domain.BaseBuildFacility;
import com.usky.cdi.domain.DmpDevice;
import com.usky.cdi.service.BaseBuildFacilityService;
import com.usky.cdi.service.DmpDeviceInfoService;
import com.usky.cdi.service.config.mqtt.MqttOutConfig;
import com.usky.cdi.service.mqtt.MqttConnectionTool;
import com.usky.cdi.service.util.SnowflakeIdGenerator;
import com.usky.cdi.service.vo.info.EngineeringBaseVO;
import com.usky.cdi.service.vo.info.FacilityDeviceVO;
import com.usky.cdi.service.vo.info.FloorPlaneVO;
import com.usky.cdi.service.vo.info.ProtectiveUnitVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 基础类数据传输服务
 * 负责向市适配平台发送基础类数据
 *
 * @author han
 * @date 2025/03/20
 */
@Slf4j
@Service
@ConditionalOnProperty(prefix = "mqtt", value = {"enabled"}, havingValue = "true")
public class BaseDataTransferService {

    @Autowired
    private BaseBuildFacilityService baseBuildFacilityService;

    @Autowired
    private DmpDeviceInfoService dmpDeviceInfoService;

    @Resource
    private MqttOutConfig.MqttGateway mqttGateway;

    // @Value("${config.engineeringID}")
    // private String engineeringID;

    @Autowired
    private MqttConnectionTool mqttConnectionTool;

    private final SnowflakeIdGenerator idGenerator;
    private final SimpleDateFormat timeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    public BaseDataTransferService() {
        // 使用默认的workerId和datacenterId，实际项目中可以从配置读取
        this.idGenerator = new SnowflakeIdGenerator(1L, 1L);
    }

    private String convertFloor(String floor) {
        if (floor == null || floor.trim().isEmpty()) {
            return floor;
        }
        try {
            int floorNum = Integer.parseInt(floor.trim());
            if (floorNum < 0) {
                return "B" + Math.abs(floorNum);
            }
        } catch (NumberFormatException e) {
            log.warn("楼层格式转换失败，原始值: {}", floor);
        }
        return floor;
    }

    private String getCurrentTime() {
        return timeFormat.format(new Date());
    }

    /**
     * 生成数据包ID
     */
    private Long generateDataPacketID() {
        return idGenerator.nextPacketId();
    }

    /**
     * 发送人防工程基础信息
     * Topic: base/engineering
     *
     * @param vo 人防工程基础信息
     * @return 是否发送成功
     */
    public boolean sendEngineeringBase(EngineeringBaseVO vo) {
        try {
            if (vo.getDataPacketID() == null) {
                vo.setDataPacketID(generateDataPacketID());
            }
            if (vo.getPublishTime() == null) {
                vo.setPublishTime(getCurrentTime());
            }

            String json = JSON.toJSONString(vo);
            String topic = "base/engineering";

            log.info("发送人防工程基础信息，Topic: {}, Data: {}", topic, json);
            mqttGateway.sendToMqtt(topic, json);

            return true;
        } catch (Exception e) {
            log.error("发送人防工程基础信息失败", e);
            return false;
        }
    }

    /**
     * 发送防护单元基础信息
     * Topic: base/protectiveUnit
     *
     * @param vo 防护单元基础信息
     * @return 是否发送成功
     */
    public boolean sendProtectiveUnit(ProtectiveUnitVO vo) {
        try {
            if (vo.getDataPacketID() == null) {
                vo.setDataPacketID(generateDataPacketID());
            }
            if (vo.getPublishTime() == null) {
                vo.setPublishTime(getCurrentTime());
            }

            String json = JSON.toJSONString(vo);
            String topic = "base/protectiveUnit";

            log.info("发送防护单元基础信息，Topic: {}, Data: {}", topic, json);
            MqttConnectionTool.MqttGateway gateway = mqttConnectionTool.connectOrRefresh(vo.getUserName(), vo.getPassword());
            gateway.sendToMqtt(topic, json);

            return true;
        } catch (Exception e) {
            log.error("发送防护单元基础信息失败", e);
            return false;
        }
    }

    /**
     * 发送楼层平面图信息
     * Topic: base/floorPlane
     *
     * @param vo 楼层平面图信息
     * @return 是否发送成功
     */
    public boolean sendFloorPlane(FloorPlaneVO vo) {
        try {
            // ========== 1. 基础参数填充 ==========
            if (vo.getDataPacketID() == null) {
                vo.setDataPacketID(generateDataPacketID());
            }
            if (vo.getPublishTime() == null) {
                vo.setPublishTime(getCurrentTime());
            }
            String imagePath = "D://142.jpg";
            // 将图片文件读取为字节数组
            byte[] imageBytes = Files.readAllBytes(Paths.get(imagePath));

            // 检查文件大小（不超过5MB）
            if (vo.getFloorFile() != null && imageBytes.length > 5 * 1024 * 1024) {
                log.error("楼层平面图文件大小超过5MB限制，FileID: {}", vo.getFloorFileID());
                return false;
            }

            HashMap<String, Object> map = new HashMap<>();
            map.put("dataPacketID", vo.getDataPacketID());
            map.put("engineeringID", vo.getEngineeringID());
            map.put("floor", vo.getFloor());
            map.put("floorFileID", vo.getFloorFileID());
            map.put("floorFileName", vo.getFloorFileName());
            map.put("floorFileSuffix", vo.getFloorFileSuffix());
            map.put("filePixWidth", vo.getFilePixWidth());
            map.put("filePixHeight", vo.getFilePixHeight());
            map.put("floorFile", imageBytes);
            map.put("publishTime", vo.getPublishTime());
            Gson gson = new Gson();
            // 将字节数组转换为Base64编码
            JSONObject jsonObject = (JSONObject) JSON.toJSON(vo);
            vo.setFloorFile(imageBytes);
//            jsonObject.put("floorFile", imageBytes);
            if (vo.getFloorFile() != null) {
                // 使用Base64编码传输二进制数据
                String base64File = java.util.Base64.getEncoder().encodeToString(vo.getFloorFile());
                jsonObject.put("floorFile", imageBytes);
            }

            String json = jsonObject.toJSONString();
            System.out.println(gson.toJson(map));
            String topic = "base/floorPlane";

            log.info("发送楼层平面图信息，Topic: {}, FileID: {}, FileSize: {} bytes",
                    topic, vo.getFloorFileID(),
                    vo.getFloorFile() != null ? vo.getFloorFile().length : 0);

            MqttConnectionTool.MqttGateway gateway = mqttConnectionTool.connectOrRefresh(vo.getUserName(), vo.getPassword());
            gateway.sendToMqtt(topic, gson.toJson(map));

            return true;
        } catch (Exception e) {
            log.error("发送楼层平面图信息失败，FileID: {}", vo.getFloorFileID(), e);
            return false;
        }
    }

    /**
     * 根据输入的键（key）从Map中匹配并返回对应的值
     * @param key 要匹配的键（输入值）
     * @param dataMap 存储键值对的Map
     * @return 匹配到的值（若未匹配到返回null）
     */
    public static <K, V> V matchByKey(K key, Map<K, V> dataMap) {
        // 判空处理（避免空指针）
        if (key == null || dataMap == null) {
            return null;
        }
        // 直接通过Map的get方法匹配
        return dataMap.get(key);
    }

    /**
     * 发送智能监管物联设施信息
     * Topic: base/sensorInfo
     *
     * @param vo 智能监管物联设施信息
     * @return 是否发送成功
     */
    public boolean sendSensorInfo(FacilityDeviceVO vo) {
        try {
            Map<Integer, Integer> userIdToName = new HashMap<>();
            userIdToName.put(702, 31);
            // 30：网络监控摄像机（可兼用平时摄像机）
            // userIdToName.put(717, 30);
            // 20：人员统计-掩蔽人数双目统计摄像机
            // userIdToName.put(719, 20);
            // 33：人员闯入-人员闯入监测传感器
            userIdToName.put(703, 33);
            userIdToName.put(704, 11);
            userIdToName.put(705, 11);
            userIdToName.put(707, 19);
            userIdToName.put(708, 19);
            userIdToName.put(709, 15);
            userIdToName.put(710, 16);
            userIdToName.put(711, 2);
            // userIdToName.put(712, 34);
            // userIdToName.put(713, 36);
            userIdToName.put(714, 37);
            userIdToName.put(716, 26);
            // 柴油发电机蓄电池监测传感器
            userIdToName.put(720, 12);

            HashMap<String, Object> map = new HashMap<>();
            map.put("dataPacketID", generateDataPacketID());
            map.put("engineeringID", vo.getEngineeringID());
            map.put("floor", convertFloor(vo.getFloor()));
            map.put("floorFileID", 1);
            map.put("sensorID", Integer.parseInt(vo.getDeviceId()));
            map.put("sensorNo", vo.getDeviceUuid());
            map.put("sensorType", matchByKey(vo.getDeviceType(), userIdToName));
            map.put("unitName", vo.getFacilityDesc());
            map.put("monitorObjNo", vo.getFacilityNum());
            map.put("monitorObj", vo.getFacilityName());
            map.put("location", vo.getAddress());
//            map.put("xCoordinate", (int) Math.floor(Double.parseDouble(vo.getPlaneX())*4.34));
//            map.put("yCoordinate", (int) Math.floor(Double.parseDouble(vo.getPlaneY())*4.34));
            map.put("xCoordinate", Integer.valueOf(vo.getPlaneX()));
            map.put("yCoordinate", Integer.valueOf(vo.getPlaneY()));
            map.put("publishTime", getCurrentTime());
            Gson gson = new Gson();
            String topic = "base/sensorInfo";
            System.out.println(gson.toJson(map));
            log.info("发送智能监管物联设施信息，Topic: {}, SensorID: {}", topic, vo.getDeviceId());
            MqttConnectionTool.MqttGateway gateway = mqttConnectionTool.connectOrRefresh(vo.getUserName(), vo.getPassword());
            gateway.sendToMqtt(topic, gson.toJson(map));

            return true;
        } catch (Exception e) {
            log.error("发送智能监管物联设施信息失败", e);
            return false;
        }
    }

    /**
     * 批量发送防护单元基础信息
     *
     * @param units 防护单元列表
     * @return 成功发送的数量
     */
    public int batchSendProtectiveUnits(java.util.List<ProtectiveUnitVO> units) {
        if (units == null || units.isEmpty()) {
            return 0;
        }

        int successCount = 0;
        for (ProtectiveUnitVO unit : units) {
            if (sendProtectiveUnit(unit)) {
                successCount++;
            }
        }

        log.info("批量发送防护单元基础信息，总数: {}, 成功: {}", units.size(), successCount);
        return successCount;
    }

    /**
     * 批量发送智能监管物联设施信息
     *
     * @param tenantId 租户ID
     * @return 成功发送的数量
     */
    public Map<String, Integer> batchSendSensorInfos(Integer tenantId, Long engineeringId, String username, String password) {
        List<BaseBuildFacility> list = baseBuildFacilityService.facilityInfo(tenantId);
        List<DmpDevice> list1 = dmpDeviceInfoService.deviceInfo(tenantId);
        List<FacilityDeviceVO> list2 = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list) && CollectionUtils.isNotEmpty(list1)) {
            for (int j = 0; j < list.size(); j++) {
                for (int k = 0; k < list1.size(); k++) {
                    if (list.get(j).getDeviceId().equals(list1.get(k).getDeviceId())) {
                        FacilityDeviceVO facilityDeviceVO = new FacilityDeviceVO();
                        facilityDeviceVO.setFloor(list.get(j).getFloor());
                        facilityDeviceVO.setFacilityName(list.get(j).getFacilityName());
                        facilityDeviceVO.setFacilityNum(list.get(j).getFacilityNum());
                        facilityDeviceVO.setDeviceId(list.get(j).getDeviceId());
                        facilityDeviceVO.setAddress(list.get(j).getAddress());
                        facilityDeviceVO.setPlaneX(list.get(j).getPlaneX());
                        facilityDeviceVO.setPlaneY(list.get(j).getPlaneY());
                        facilityDeviceVO.setDeviceUuid(list1.get(k).getDeviceUuid());
                        facilityDeviceVO.setFacilityDesc(list.get(j).getFacilityDesc());
                        facilityDeviceVO.setDeviceType(list1.get(k).getDeviceType());
                        facilityDeviceVO.setEngineeringID(engineeringId);
                        facilityDeviceVO.setUserName(username);
                        facilityDeviceVO.setPassword(password);
                        list2.add(facilityDeviceVO);
                    }
                }
            }
        }
        int successCount = 0, failCount = 0, notSynced = 0;
        if (CollectionUtils.isNotEmpty(list2)) {
            for (int i = 0; i < list2.size(); i++) {
                if (sendSensorInfo(list2.get(i))) {
                    successCount++;
                } else {
                    failCount++;
                }
            }
        }
        notSynced = list2.size() - successCount - failCount;
        log.info("批量发送智能监管物联设施信息，总数: {}, 成功: {}, 失败: {}, 未同步: {}", list2.size(), successCount, failCount, notSynced);

        Map<String, Integer> map = new HashMap<>();
        map.put("total", list2.size());
        map.put("success", successCount);
        map.put("failure", failCount);
        map.put("notSynced", notSynced);
        return map;
    }
}

