package com.ruoyi.websocket.server;

import org.springframework.web.socket.*;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

public class GameRoomWebSocketHandler extends TextWebSocketHandler {

    // 存储所有连接的会话
    private static final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 1. 从路径参数中获取 roomId 和 userId
        String roomId = getPathVariable(session, "roomId");
        String userId = getPathVariable(session, "userId");

        // 如果从路径参数获取失败，尝试从 URI 中解析
        if (roomId == null || userId == null) {
            Map<String, String> pathVariables = extractPathVariablesFromUri(session);
            roomId = pathVariables.get("roomId");
            userId = pathVariables.get("userId");
        }

        // 2. 关联会话到房间
        String sessionKey = roomId + "_" + userId;
        sessions.put(sessionKey, session);


        System.out.println("大帅" + " 加入房间: " + roomId + ", userId: " + userId);

        // 4. 发送欢迎消息
        Map<String, Object> welcomeMsg = new HashMap<>();
        welcomeMsg.put("type", "system");
        welcomeMsg.put("message", "欢迎加入房间: " + roomId);
        welcomeMsg.put("roomId", roomId);
        welcomeMsg.put("userId", userId);
        welcomeMsg.put("timestamp", System.currentTimeMillis());

        sendJsonMessage(session, welcomeMsg);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String roomId = getPathVariable(session, "roomId");
        String userId = getPathVariable(session, "userId");

        // 如果从路径参数获取失败，尝试从 URI 中解析
        if (roomId == null || userId == null) {
            Map<String, String> pathVariables = extractPathVariablesFromUri(session);
            roomId = pathVariables.get("roomId");
            userId = pathVariables.get("userId");
        }


        String payload = message.getPayload();
        System.out.println("房间 " + roomId + " 收到用户大帅 " + userId + " 的消息: " + payload);

        try {
            // 解析客户端发送的 JSON 消息
            Map<String, Object> clientMessage = objectMapper.readValue(payload, Map.class);
            String msgType = (String) clientMessage.getOrDefault("type", "chat");

            Map<String, Object> broadcastMsg = new HashMap<>();
            broadcastMsg.put("type", msgType);
            broadcastMsg.put("userId", userId);
            broadcastMsg.put("roomId", roomId);
            broadcastMsg.put("content", clientMessage.get("content"));
            broadcastMsg.put("timestamp", System.currentTimeMillis());

            broadcastJsonToRoom(roomId, broadcastMsg);

        } catch (Exception e) {
            System.out.println("解析客户端消息失败，按文本处理: " + e.getMessage());

            Map<String, Object> broadcastMsg = new HashMap<>();
            broadcastMsg.put("type", "chat");
            broadcastMsg.put("userId", userId);
            broadcastMsg.put("roomId", roomId);
            broadcastMsg.put("content", payload);
            broadcastMsg.put("timestamp", System.currentTimeMillis());

            broadcastJsonToRoom(roomId, broadcastMsg);
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        String roomId = getPathVariable(session, "roomId");
        String userId = getPathVariable(session, "userId");

        // 如果从路径参数获取失败，尝试从 URI 中解析
        if (roomId == null || userId == null) {
            Map<String, String> pathVariables = extractPathVariablesFromUri(session);
            roomId = pathVariables.get("roomId");
            userId = pathVariables.get("userId");
        }

        String sessionKey = roomId + "_" + userId;
        sessions.remove(sessionKey);
        System.out.println("用户大帅 " + userId + " 退出房间: " + roomId);

        // 通知其他用户有人离开
        Map<String, Object> leaveMsg = new HashMap<>();
        leaveMsg.put("type", "system");
        leaveMsg.put("message", "用户大帅 " + userId + " 已离开房间");
        leaveMsg.put("userId", userId);
        leaveMsg.put("roomId", roomId);
        leaveMsg.put("timestamp", System.currentTimeMillis());

        broadcastJsonToRoom(roomId, leaveMsg);
    }

    // 辅助方法：从路径参数中提取变量（Spring 标准方式）
    private String getPathVariable(WebSocketSession session, String name) {
        Map<String, String> vars = (Map<String, String>) session.getAttributes().get("org.springframework.web.socket.WebSocketHandler.uriVariables");
        return vars != null ? vars.get(name) : null;
    }

    // 辅助方法：从 URI 中手动解析路径参数
    private Map<String, String> extractPathVariablesFromUri(WebSocketSession session) {
        Map<String, String> pathVariables = new HashMap<>();
        try {
            URI uri = session.getUri();
            if (uri != null) {
                String path = uri.getPath();
                String[] segments = path.split("/");

                // 根据路径模式 /websocket/{roomId}/{userId} 解析
                if (segments.length >= 4) {
                    pathVariables.put("roomId", segments[segments.length - 2]);
                    pathVariables.put("userId", segments[segments.length - 1]);
                }
            }
        } catch (Exception e) {
            System.err.println("从 URI 解析路径参数失败: " + e.getMessage());
        }
        return pathVariables;
    }

    // 辅助方法：发送 JSON 消息
    private void sendJsonMessage(WebSocketSession session, Map<String, Object> message) throws Exception {
        String jsonMessage = objectMapper.writeValueAsString(message);
        session.sendMessage(new TextMessage(jsonMessage));
    }

    // 辅助方法：广播 JSON 消息到指定房间
    private void broadcastJsonToRoom(String roomId, Map<String, Object> message) throws Exception {
        String jsonMessage = objectMapper.writeValueAsString(message);
        for (Map.Entry<String, WebSocketSession> entry : sessions.entrySet()) {
            if (entry.getKey().startsWith(roomId + "_")) {
                WebSocketSession session = entry.getValue();
                if (session.isOpen()) {
                    session.sendMessage(new TextMessage(jsonMessage));
                }
            }
        }
    }
}