package com.ruoyi.ws;

import javax.websocket.CloseReason;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.ws.config.WebSocketAuthConfigurator;
import com.ruoyi.ws.service.WebSocketService;

/**
 * WebSocket服务类
 */
@ServerEndpoint(value = "/ws/message", configurator = WebSocketAuthConfigurator.class)
@Component
@Slf4j
public class MessageWebSocket {
    /**
     * 建立连接
     */
    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        try {
            String token = (String) config.getUserProperties().get("token");
            if (token != null) {
                TokenService tokenService = SpringUtils.getBean(TokenService.class);
                WebSocketService webSocketService = SpringUtils.getBean(WebSocketService.class);
                LoginUser loginUser = tokenService.getLoginUser(token);
                tokenService.verifyToken(loginUser);
                if (loginUser != null) {
                    Long userId = loginUser.getUserId();
                    webSocketService.addSession(userId, session);
                    log.info("用户{}连接WebSocket成功", userId);
                    return;
                }
            }
            session.close(new CloseReason(CloseReason.CloseCodes.VIOLATED_POLICY, "未认证"));
        } catch (Exception e) {
            log.error("WebSocket连接异常", e);
        }
    }

    /**
     * 关闭连接
     */
    @OnClose
    public void onClose() {
        try {
            LoginUser loginUser = SecurityUtils.getLoginUser();
            if (loginUser != null) {
                Long userId = loginUser.getUserId();
                WebSocketService webSocketService = SpringUtils.getBean(WebSocketService.class);
                webSocketService.removeSession(userId);
                log.info("用户{}断开WebSocket连接", userId);
            }
        } catch (Exception e) {
            log.error("WebSocket关闭异常", e);
        }
    }

    /**
     * 错误处理
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("WebSocket发生错误", error);
    }
}
