package com.ruoyi.framework.websocket;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.system.domain.UserLocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.List;
import java.util.concurrent.Semaphore;

@Component
@ServerEndpoint("/websocket/location/{userId}")
public class LocationWebSocketServer {
    private static final Logger LOGGER = LoggerFactory.getLogger(LocationWebSocketServer.class);
    private static final int MAX_ONLINE_COUNT = 1000;
    private static final Semaphore SEMAPHORE = new Semaphore(MAX_ONLINE_COUNT);

    private static volatile LocationService locationService;
    private static volatile ObjectMapper objectMapper;

    public static void setLocationService(LocationService service) {
        LocationWebSocketServer.locationService = service;
    }

    public static void setObjectMapper(ObjectMapper mapper) {
        LocationWebSocketServer.objectMapper = mapper;
    }

    @OnOpen
    public void onOpen(@PathParam("userId") String userId, Session session) {
        try {
            if (!SemaphoreUtils.tryAcquire(SEMAPHORE)) {
                WebSocketUsers.sendMessageToUserByText(session, "当前在线人数超过限制：" + MAX_ONLINE_COUNT);
                session.close();
                return;
            }

            // 保存用户连接
            WebSocketUsers.put(userId, session);
            LOGGER.info("用户[{}]建立连接", userId);

            // 发送当前在线人数
            String message = String.format("连接成功，当前在线人数：%d", WebSocketUsers.getOnlineCount());
            WebSocketUsers.sendMessageToUserByText(session, message);
        } catch (Exception e) {
            LOGGER.error("连接建立失败", e);
            SemaphoreUtils.release(SEMAPHORE);
        }
    }

    private void checkDependencies() {
        if (locationService == null || objectMapper == null) {
            throw new IllegalStateException("必要的依赖未注入，请检查LocationService和ObjectMapper是否已经设置");
        }
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        try {
            checkDependencies();

            String userId = WebSocketUsers.getUserId(session);
            if (userId == null) {
                WebSocketUsers.sendMessageToUserByText(session, "未找到用户信息，请重新连接");
                return;
            }

            LOGGER.info("收到用户[{}]的消息: {}", userId, message);
            UserLocation location = objectMapper.readValue(message, UserLocation.class);

            // 验证用户ID是否匹配
            if (!userId.equals(location.getUserId())) {
                WebSocketUsers.sendMessageToUserByText(session, "用户ID不匹配");
                return;
            }

            locationService.updateLocation(location);
            List<UserLocation> nearbyUsers = locationService.getNearbyUsers(location.getUserId(), 5.0);
            String responseMessage = objectMapper.writeValueAsString(nearbyUsers);

            WebSocketUsers.sendMessageToUserByText(session, responseMessage);
        } catch (Exception e) {
            LOGGER.error("处理消息失败", e);
            WebSocketUsers.sendMessageToUserByText(session, "消息处理失败: " + e.getMessage());
        }
    }

    @OnClose
    public void onClose(Session session) {
        WebSocketUsers.remove(session);
        SemaphoreUtils.release(SEMAPHORE);
        LOGGER.info("关闭连接 - {}", session.getId());
    }

    @OnError
    public void onError(Session session, Throwable error) {
        LOGGER.error("WebSocket错误", error);
        WebSocketUsers.remove(session);
        SemaphoreUtils.release(SEMAPHORE);
    }
}
