package com.ruoyi.redis;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import com.ruoyi.websocket.server.GameRoomWebSocketHandler;
import java.io.IOException;
import java.util.Map;

@Component
public class RedisMessageSubscriber {
    
    @Autowired
    private ObjectMapper objectMapper;//是jackson里面的方法，主要处理序列化和反序列化

    /**
     * 处理从Redis订阅到的消息
     */
    public void onMessage(String redisMessage, String channel) {
        try {
            // 解析消息，其中应包含房间ID和要发送的实际消息体
            Map<String, Object> messageMap = objectMapper.readValue(redisMessage, Map.class);
            String targetRoomId = (String) messageMap.get("roomId");
            Map<String, Object> actualMessageToSend = (Map<String, Object>) messageMap.get("message");
            
            // 调用本地广播方法，只发送给本实例内指定房间的用户
            broadcastToLocalRoom(targetRoomId, actualMessageToSend);
            
        } catch (Exception e) {
            System.err.println("处理Redis消息失败: " + e.getMessage());
        }
    }

    /**
     * 仅向本地会话（即当前JVM内的WebSocketSession）广播消息
     */
    private void broadcastToLocalRoom(String roomId, Map<String, Object> message) throws Exception {
        // 遍历原Handler中的sessions变量（需稍作调整使其可被访问）
        for (Map.Entry<String, WebSocketSession> entry : GameRoomWebSocketHandler.getSessions().entrySet()) {
            String sessionKey = entry.getKey();
            if (sessionKey.startsWith(roomId + "_")) { // 判断是否属于目标房间
                WebSocketSession session = entry.getValue();
                if (session != null && session.isOpen()) {
                    try {
                        String jsonMessage = objectMapper.writeValueAsString(message);
                        session.sendMessage(new TextMessage(jsonMessage));
                    } catch (IOException e) {
                        System.err.println("向本地会话发送消息失败: " + e.getMessage());
                    }
                }
            }
        }
    }
}