package com.qaup.collision.websocket.handler;

import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;

/**
 * 冲突检测WebSocket处理器
 * 基于Spring WebSocket框架实现，专门用于冲突检测系统的实时消息推送
 * 
 * @author qaup-collision
 */
@Component
public class CollisionWebSocketHandler implements WebSocketHandler {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(CollisionWebSocketHandler.class);
    
    // 存储所有连接的WebSocket会话
    private final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
    
    @Override
    public void afterConnectionEstablished(@NonNull WebSocketSession session) throws Exception {
        String sessionId = session.getId();
        sessions.put(sessionId, session);
        
        LOGGER.info("🔗 冲突检测WebSocket连接建立 - 会话ID: {}", sessionId);
        LOGGER.info("📊 当前连接数: {}", sessions.size());
        
        // 发送连接成功消息
        String welcomeMessage = String.format(
            "{\"type\":\"connection\",\"status\":\"connected\",\"message\":\"冲突检测WebSocket连接成功\",\"sessionId\":\"%s\",\"timestamp\":%d}",
            sessionId, System.currentTimeMillis()
        );
        
        sendMessage(session, welcomeMessage);
    }

    @Override
    public void handleMessage(@NonNull WebSocketSession session, @NonNull WebSocketMessage<?> message) throws Exception {
        String sessionId = session.getId();
        String payload = message.getPayload().toString();
        
        LOGGER.debug("📨 收到消息 - 会话ID: {}, 消息: {}", sessionId, payload);
        
        // 处理客户端消息
        if ("ping".equals(payload)) {
            // 心跳检测响应
            String pongMessage = String.format(
                "{\"type\":\"pong\",\"timestamp\":%d}", 
                System.currentTimeMillis()
            );
            sendMessage(session, pongMessage);
        } else if (payload.contains("subscribe")) {
            // 订阅消息处理
            String subscribeResponse = String.format(
                "{\"type\":\"subscribe\",\"status\":\"success\",\"message\":\"订阅成功\",\"timestamp\":%d}",
                System.currentTimeMillis()
            );
            sendMessage(session, subscribeResponse);
        } else {
            // 回显消息
            String echoMessage = String.format(
                "{\"type\":\"echo\",\"originalMessage\":\"%s\",\"timestamp\":%d}",
                payload, System.currentTimeMillis()
            );
            sendMessage(session, echoMessage);
        }
    }

    @Override
    public void handleTransportError(@NonNull WebSocketSession session, @NonNull Throwable exception) throws Exception {
        String sessionId = session.getId();
        LOGGER.error("❌ WebSocket传输错误 - 会话ID: {}", sessionId, exception);
        
        // 清理会话
        sessions.remove(sessionId);
        
        if (session.isOpen()) {
            session.close(CloseStatus.SERVER_ERROR);
        }
    }

    @Override
    public void afterConnectionClosed(@NonNull WebSocketSession session, @NonNull CloseStatus closeStatus) throws Exception {
        String sessionId = session.getId();
        sessions.remove(sessionId);
        
        LOGGER.info("🔌 WebSocket连接关闭 - 会话ID: {}, 状态: {}", sessionId, closeStatus);
        LOGGER.info("📊 当前连接数: {}", sessions.size());
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    /**
     * 发送消息给指定会话（线程安全）
     */
    private void sendMessage(WebSocketSession session, String message) {
        try {
            if (session.isOpen()) {
                // 添加同步锁确保同一个会话的消息发送是串行的
                synchronized (session) {
                    if (session.isOpen()) { // 再次检查状态
                        session.sendMessage(new TextMessage(message));
                    }
                }
            }
        } catch (Exception e) {
            LOGGER.error("发送消息失败 - 会话ID: {}", session.getId(), e);
        }
    }

    /**
     * 广播消息给所有连接的客户端
     */
    public void broadcastMessage(String message) {
        sessions.values().forEach(session -> sendMessage(session, message));
    }

    /**
     * 发送消息给指定会话ID的客户端
     */
    public void sendMessageToSession(String sessionId, String message) {
        WebSocketSession session = sessions.get(sessionId);
        if (session != null) {
            sendMessage(session, message);
        }
    }

    /**
     * 获取当前连接数
     */
    public int getConnectionCount() {
        return sessions.size();
    }
} 