package com.agri.framework.manager;

import com.agri.framework.config.MqttConfig;
import com.agri.framework.interceptor.FrontendControlHandler;
import com.agri.system.domain.SysAgriInfo;
import com.agri.system.service.AgriService;
import com.agri.system.service.ISysAgriInfoService;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class AgriStatusManager {

    private static final Logger log = LoggerFactory.getLogger(AgriStatusManager.class);

    // Redis 前缀常量
    private static final String SUB_KEY_PREFIX = "sub:";

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private MqttConfig.MqttMessageSender mqttMessageSender;


    // JSON序列化工具（单例）
    private final ObjectMapper objectMapper = new ObjectMapper();

    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @Resource
    private FrontendControlHandler frontendControlHandler;
    @Autowired
    private AgriService agriService;

    // ========== 批量查在线状态（Pipeline 优化版，JDK 8 适配） ==========
    // 在线离线的都得推
    public Map<String, Map<String, Boolean>> batchCheckDeviceOnline(List<String> imeiList) {
        Map<String, Map<String, Boolean>> result = new HashMap<>();
        if (imeiList.isEmpty()) {
            return result;
        }

        // JDK 8 显式声明 RedisCallback，避免 Lambda 泛型问题
        List<Object> results = stringRedisTemplate.executePipelined(
                new RedisCallback<Object>() {
                    @Override
                    public Object doInRedis(RedisConnection connection) {
                        StringRedisSerializer serializer = new StringRedisSerializer();
                        for (String imei : imeiList) {
                            byte[] onlineKeyBytes = serializer.serialize(SUB_KEY_PREFIX + imei);
                            connection.exists(onlineKeyBytes); // 批量执行 exists
                            connection.exists(serializer.serialize(imei));
                        }
                        return null;
                    }
                },
                new StringRedisSerializer()
        );

        // 解析结果：每两个结果对应一个IMEI（subExist + imeiOnline）
        for (int i = 0; i < imeiList.size(); i++) {
            String imei = imeiList.get(i);
            // 初始化默认状态：不存在+离线
            boolean subExist = false;
            boolean imeiOnline = false;

            // 越界判断：避免IndexOutOfBoundsException
            int subIndex = i * 2;
            int imeiIndex = i * 2 + 1;
            if (subIndex < results.size()) {
                Object subResult = results.get(subIndex);
                subExist = parseExistsResult(subResult);
            }
            if (imeiIndex < results.size()) {
                Object imeiResult = results.get(imeiIndex);
                imeiOnline = parseExistsResult(imeiResult);
            }
            result.put(imei, ImmutableMap.of("subExist", subExist, "imeiOnline", imeiOnline));
        }
        return result;
    }
    private boolean parseExistsResult(Object result) {
        if (result instanceof Long) {
            return ((Long) result) == 1;
        } else if (result instanceof Boolean) {
            return (Boolean) result;
        }
        return false;
    }
    // ========== 核心方法3：异步批量推送在线状态到 MQTT（线程池隔离） ==========
    @Async("mqttPushExecutor")
    public void asyncBatchPushMqtt(Map<String, Map<String, Boolean>> statusMap) {
        if (statusMap.isEmpty()) {
            log.info("不存在任何imei");
            return;
        }
        int successCount = 0;
        int failCount = 0;
        String dateNow = LocalDateTime.now().format(DATE_TIME_FORMATTER);
        // 在线状态
        for (Map.Entry<String, Map<String, Boolean>> map : statusMap.entrySet()) {
            String imei = map.getKey();
            try {
                // 按你的需求，直接推送到 frontend/{imei}/online 主题
                Map<String, Boolean> imeiMap = map.getValue();

                // 设备在线的 && 推送首页状态 离线在线都推
                if (imeiMap.get("subExist")) {
                    // 构造首页消息（用ObjectMapper序列化，避免手动拼接JSON）
                    Map<String, Object> onlineMsg = new HashMap<>();
                    onlineMsg.put("online", imeiMap.get("imeiOnline") ? "在线" : "离线");
                    onlineMsg.put("time", dateNow); // 毫秒时间戳
                    onlineMsg.put("imei", imei);
                    String onlineMessage = objectMapper.writeValueAsString(onlineMsg);
                    mqttMessageSender.publish("device/" + imei + "/status", onlineMessage);
                }
                successCount++;
            } catch (Exception e) {
                failCount++;
                log.error("向设备 {} 推送在线状态失败", imei, e);
            }

        }

        log.info("批量在线状态推送完成：成功={}，失败={}", successCount, failCount);
    }
}
