package com.ssyf.ws.handler.system;

import cn.hutool.core.util.StrUtil;
import com.ssyf.ws.constants.CommandType;
import com.ssyf.ws.constants.WebSocketConstants;
import com.ssyf.ws.domain.WsMessage;
import com.ssyf.ws.service.WsClientService;
import com.ssyf.ws.service.SessionService;
import com.ssyf.ws.service.UserStatusService;
import com.ssyf.ws.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;

import java.util.Map;

/**
 * WebSocket消息处理器
 * 处理连接建立、消息接收、连接关闭等事件
 */
@Slf4j
@Component
public class WebWsMainHandler implements WebSocketHandler {

    @Autowired
    private MessageDispatcher messageDispatcher;
    
    @Autowired
    private SessionService sessionService;
    
    @Autowired
    private UserStatusService userStatusService;

    @Autowired
    private WsClientService wsClientService;

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        // 获取认证信息
        Map<String, Object> attributes = session.getAttributes();
        String token = (String) attributes.get(WebSocketConstants.TOKEN_KEY);
        if(StrUtil.isNotBlank( token)){
            this.wsClientService.validToken(token, session);
        }
        String masterAccountId = (String) attributes.get("masterAccountId");
        String fansAccountId = (String) attributes.get("fansAccountId");
        if(StrUtil.isNotBlank(masterAccountId) && StrUtil.isNotBlank(fansAccountId)){
            this.wsClientService.initChatSession(session, masterAccountId, fansAccountId);
        }
        String clientId = (String) attributes.get(WebSocketConstants.SESSION_ATTR_USER_ID);
        log.info("WebSocket连接建立成功: clientId={}, sessionId={}" , clientId, session.getId());
    }

    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        if (!(message instanceof TextMessage)) {
            log.warn("不支持的消息类型: {}", message.getClass().getSimpleName());
            return;
        }
        
        String payload = ((TextMessage) message).getPayload();
        log.debug("接收到WebSocket消息: sessionId={}, payload={}", session.getId(), payload);
        
        try {
            // 解析消息
            WsMessage wsMessage = JsonUtils.fromJson(payload, WsMessage.class);
            if (wsMessage == null) {
                log.error("消息解析失败: {}", payload);
                this.wsClientService.sendErrorMessage(session,wsMessage, "消息格式错误");
                return;
            }

            // 验证消息基本格式
            if (wsMessage.getCommand() == null) {
                log.error("消息缺少命令类型: {}", payload);
                this.wsClientService.sendErrorMessage(session,wsMessage, "缺少命令错误");
                return;
            }
            CommandType commandType = CommandType.getByCode(wsMessage.getCommand());
            if(commandType == null){
                log.error("不支持的命令类型: {}", payload);
                this.wsClientService.sendErrorMessage(session,wsMessage, "不支持的命令错误");
                return;
            }
            if(commandType.isAuth()){
                // 验证token
                boolean b = this.wsClientService.validToken(session);
                if(!b){
                    log.error("WebSocket验证Token失败: sessionId={}", session.getId());
                    this.wsClientService.sendErrorMessage(session ,wsMessage, "Token验证失败");
                    return;
                }
            }

            // 更新会话活跃时间
            sessionService.updateLastActiveTime(session.getId());
            
            // 分发消息处理
            messageDispatcher.dispatch(session, wsMessage);
            
        } catch (Exception e) {
            log.error("处理WebSocket消息时发生异常: sessionId={}, payload={}", session.getId(), payload, e);
            this.wsClientService.sendErrorMessage(session, "服务器内部错误");
        }
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        log.error("WebSocket传输错误: sessionId={}", session.getId(), exception);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
       this.wsClientService.closeSession(session);
    }

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