package com.ssyf.ws.handler.system;

import com.ssyf.ws.constants.CommandType;
import com.ssyf.ws.domain.Command;
import com.ssyf.ws.domain.WsMessage;
import com.ssyf.ws.domain.SessionInfo;
import com.ssyf.ws.handler.CommandHandler;
import com.ssyf.ws.service.SessionService;
import com.ssyf.ws.service.WsClientService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketSession;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 消息分发器
 * 负责将不同类型的消息分发给对应的处理器
 */
@Slf4j
@Component
public class MessageDispatcher {

    @Autowired
    private SessionService sessionService;

    @Autowired
    private WsClientService wsClientService;

    // 命令处理器映射表
    private final Map<CommandType, CommandHandler> handlerMap = new ConcurrentHashMap<>();

    /**
     * 注册命令处理器
     */
    public void registerHandler(CommandType commandType, CommandHandler handler) {
        handlerMap.put(commandType, handler);
        log.debug("注册命令处理器: {} -> {}", commandType, handler.getClass().getSimpleName());
    }

    /**
     * 分发消息处理
     */
    public void dispatch(WebSocketSession session, WsMessage message) {
        CommandType commandType = CommandType.getByCode(message.getCommand());
        
        // 获取会话信息
        SessionInfo sessionInfo = sessionService.getSession(session.getId());
        // 构建命令对象
        Command command = new Command();
        command.setType(commandType);
        command.setSession(sessionInfo);
        command.setOriginalMessage(message);
        
        // 查找对应的处理器
        CommandHandler handler = handlerMap.get(commandType);
        if (handler == null) {
            log.warn("未找到对应的命令处理器: commandType={}", commandType);
            return;
        }
        
        try {
            // 执行命令处理
            log.debug("开始处理命令: commandType={}, sessionId={}", commandType, session.getId());
            handler.handle(command, session);
            log.debug("命令处理完成: commandType={}, sessionId={}", commandType, session.getId());
        } catch (Exception e) {
            log.error("命令处理异常: commandType={}, sessionId={}", commandType, session.getId(), e);
            wsClientService.sendErrorMessage(session ,message, "服务器内部错误");
        }
    }

    /**
     * 获取处理器映射表（用于测试和监控）
     */
    public Map<CommandType, CommandHandler> getHandlerMap() {
        return new ConcurrentHashMap<>(handlerMap);
    }
}