package com.cmvr.framework.websocket.server;


import com.cmvr.framework.websocket.manager.ChannelSubscriptionManager;
import com.cmvr.framework.websocket.manager.WSSessionManager;
import com.cmvr.framework.websocket.registry.MessageHandlerRegistry;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.net.URI;
import java.util.Objects;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * WebSocket 消息处理器（支持用户限流、消息推送）
 */
public class WSServer extends TextWebSocketHandler {

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

    // 最大并发连接数
    public static final int MAX_ONLINE_COUNT = 100;

    // 限流控制
    private static final Semaphore SEMAPHORE = new Semaphore(MAX_ONLINE_COUNT);


    // 当前在线人数
    private static final AtomicInteger ONLINE_COUNT = new AtomicInteger(0);


    private final ObjectMapper objectMapper = new ObjectMapper();


    @Autowired
    private MessageHandlerRegistry registry;

    @Autowired
    private WSSessionManager sessionManager;

    @Autowired
    private ChannelSubscriptionManager channelSubscriptionManager;

    @Override
    public void afterConnectionEstablished(@NotNull WebSocketSession session) throws Exception {
        if (!SEMAPHORE.tryAcquire()) {
            log.warn("连接拒绝：超过最大在线人数 {}", MAX_ONLINE_COUNT);
            registry.handle(session, "common", buildCommonMessage("当前在线人数超过限制：" + MAX_ONLINE_COUNT));
            session.close();
            return;
        }
        String userId = extractUserIdFromUri(Objects.requireNonNull(session.getUri()));
        if (userId != null) {
            session.getAttributes().put("userId", userId);
        } else {
            System.err.println("无法从 URI 中提取 userId");
        }
        session.setBinaryMessageSizeLimit(1024 * 1024 * 10); // 设置最大接收消息大小为 10MB
        sessionManager.addSession(session);
        ONLINE_COUNT.incrementAndGet();
        log.info("WebSocket连接建立：sid={}，当前在线：{}", userId, ONLINE_COUNT.get());
    }

    @Override
    protected void handleTextMessage(@NotNull WebSocketSession session, TextMessage message) throws Exception {
        JsonNode jsonNode = objectMapper.readTree(message.getPayload());
        String type = jsonNode.get("type").asText();

        registry.handle(session, type, jsonNode);
    }

    @Override
    public void afterConnectionClosed(@NotNull WebSocketSession session, @NotNull CloseStatus status) throws Exception {
        ONLINE_COUNT.decrementAndGet();
        SEMAPHORE.release();

        sessionManager.removeSession(session);
        // 清除通道session
        channelSubscriptionManager.clearSession(session);
        log.info("连接关闭 sid={}，当前在线：{}", session.getAttributes().get("userId"), ONLINE_COUNT.get());
    }


    public static JsonNode buildCommonMessage(String content) {
        ObjectNode node = new ObjectMapper().createObjectNode();
        node.put("type", "common");
        node.put("sender", "system");
        node.put("content", content);
        return node;
    }

    private String extractUserIdFromUri(URI uri) {
        String query = uri.getQuery();
        if (query != null) {
            for (String param : query.split("&")) {
                if (param.startsWith("userId=")) {
                    return param.split("=")[1];
                }
            }
        }
        return null;
    }


}
