#include "server/ClientHandler.h"
#include "server/GameServer.h"
#include "server/GameLobby.h"
#include "server/BattleRoomManager.h"
#include "common/Protocol.h"
#include <iostream>
#include <cstring>

#ifdef _WIN32
    #include <winsock2.h>
#else
    #include <sys/socket.h>
    #include <unistd.h>
#endif

ClientHandler::ClientHandler(int clientId, SocketFd socketFd, GameServer* server)
    : m_clientId(clientId),
      m_socketFd(socketFd),
      m_server(server),
      m_isRunning(false),
      m_state(ClientState::Unauthenticated),
      m_userId(-1),
      m_battleRoomId(-1) {
}

ClientHandler::~ClientHandler() {
    stop();
}

void ClientHandler::start() {
    m_isRunning = true;
    m_thread = std::thread(&ClientHandler::run, this);
}

void ClientHandler::stop() {
    if (!m_isRunning) {
        return;
    }
    
    m_isRunning = false;
    
    // 关闭socket
    #ifdef _WIN32
        closesocket(m_socketFd);
    #else
        ::close(m_socketFd);
    #endif
    
    // 只在不是当前线程时才join
    if (m_thread.joinable() && m_thread.get_id() != std::this_thread::get_id()) {
        m_thread.join();
    } else if (m_thread.joinable()) {
        m_thread.detach();  // 如果是当前线程，则分离
    }
}

bool ClientHandler::sendMessage(const std::string& message) {
    std::string fullMsg = message;
    if (fullMsg.back() != '\n') {
        fullMsg += '\n';
    }
    
    int bytesSent = ::send(m_socketFd, fullMsg.c_str(), fullMsg.length(), 0);
    return bytesSent > 0;
}

void ClientHandler::run() {
    std::cout << "ClientHandler " << m_clientId << " started (fd: " << m_socketFd << ")" << std::endl;
    
    char buffer[4096];
    std::string accumulated;
    
    while (m_isRunning) {
        // 接收数据
        int bytesRead = ::recv(m_socketFd, buffer, sizeof(buffer) - 1, 0);
        if (bytesRead <= 0) {
            // 客户端断开连接
            std::cout << "Client " << m_clientId << " disconnected" << std::endl;
            break;
        }
        
        buffer[bytesRead] = '\0';
        accumulated += buffer;
        
        // 处理完整的消息（以\n分隔）
        size_t pos;
        while ((pos = accumulated.find('\n')) != std::string::npos) {
            std::string message = accumulated.substr(0, pos);
            accumulated = accumulated.substr(pos + 1);
            
            if (message.empty()) {
                continue;
            }
            
            // 解析协议
            std::string command;
            std::vector<std::string> params;
            if (!Protocol::parseMessage(message, command, params)) {
                sendMessage(Protocol::buildResponse(false, "协议格式无效"));
                continue;
            }
            
            // 处理命令
            handleCommand(command, params);
        }
    }
    
    // 清理：通知服务器移除此客户端
    if (!m_username.empty()) {
        std::cout << "用户 " << m_username << " 已登出" << std::endl;
    }
    m_server->removeClient(m_clientId);
}

void ClientHandler::handleCommand(const std::string& command, 
                                  const std::vector<std::string>& params) {
    if (command == Protocol::C2S_REGISTER) {
        handleRegister(params);
    } else if (command == Protocol::C2S_LOGIN) {
        handleLogin(params);
    } else if (m_state == ClientState::Unauthenticated) {
        sendMessage(Protocol::buildResponse(false, "请先登录"));
    } else if (command == Protocol::C2S_CHAT) {
        handleChat(params);
    } else if (command == Protocol::C2S_LIST_PLAYERS) {
        handleListPlayers();
    } else if (command == Protocol::C2S_INVITE) {
        handleInvite(params);
    } else if (command == Protocol::C2S_INVITE_RSP) {
        handleInviteResponse(params);
    } else if (command == Protocol::C2S_BATTLE_ACTION) {
        handleBattleAction(params);
    } else if (command == Protocol::C2S_LOGOUT) {
        handleLogout();
    } else {
        sendMessage(Protocol::buildResponse(false, "未知命令"));
    }
}

void ClientHandler::handleRegister(const std::vector<std::string>& params) {
    if (params.size() < 2) {
        sendMessage(Protocol::buildResponse(false, "参数无效"));
        return;
    }
    
    const std::string& username = params[0];
    const std::string& password = params[1];
    
    if (m_server->getDatabase()->registerUser(username, password)) {
        sendMessage(Protocol::buildResponse(true, "注册成功"));
        std::cout << "新用户已注册：" << username << std::endl;
    } else {
        sendMessage(Protocol::buildResponse(false, "用户名已存在"));
    }
}

void ClientHandler::handleLogin(const std::vector<std::string>& params) {
    if (params.size() < 2) {
        sendMessage(Protocol::buildResponse(false, "参数无效"));
        return;
    }
    
    const std::string& username = params[0];
    const std::string& password = params[1];
    
    if (!m_server->getDatabase()->verifyUser(username, password)) {
        sendMessage(Protocol::buildResponse(false, "用户名或密码错误"));
        return;
    }
    
    // 获取用户ID
    int userId = m_server->getDatabase()->getUserId(username);
    if (userId < 0) {
        sendMessage(Protocol::buildResponse(false, "用户不存在"));
        return;
    }
    
    // 获取或创建角色数据
    CharacterData charData;
    if (!m_server->getDatabase()->getCharacterData(userId, charData)) {
        // 创建默认角色
        if (!m_server->getDatabase()->createCharacter(userId, "Warrior")) {
            sendMessage(Protocol::buildResponse(false, "创建角色失败"));
            return;
        }
        m_server->getDatabase()->getCharacterData(userId, charData);
    }
    
    m_username = username;
    m_userId = userId;
    m_state = ClientState::Lobby;
    
    // 发送登录成功消息
    std::string loginMsg = Protocol::buildLoginOk(username, charData.className, 
                                                  charData.level, charData.hp, charData.mp);
    sendMessage(loginMsg);
    
    std::cout << "用户 " << username << " 已登录，职业：" << charData.className << std::endl;
}

void ClientHandler::handleChat(const std::vector<std::string>& params) {
    if (params.empty()) {
        return;
    }
    
    if (m_state != ClientState::Lobby) {
        sendMessage(Protocol::buildResponse(false, "你不在游戏大厅"));
        return;
    }
    
    const std::string& message = params[0];
    m_server->getLobby()->broadcastMessage(m_username, message, m_clientId);
}

void ClientHandler::handleListPlayers() {
    std::vector<std::string> players = m_server->getOnlinePlayers();
    std::string listMsg = Protocol::buildPlayerList(players);
    sendMessage(listMsg);
}

void ClientHandler::handleInvite(const std::vector<std::string>& params) {
    if (params.empty()) {
        sendMessage(Protocol::buildResponse(false, "参数无效"));
        return;
    }
    
    if (m_state != ClientState::Lobby) {
        sendMessage(Protocol::buildResponse(false, "你不在游戏大厅"));
        return;
    }
    
    const std::string& target = params[0];
    m_server->getLobby()->handleInvite(m_username, target);
}

void ClientHandler::handleInviteResponse(const std::vector<std::string>& params) {
    if (params.size() < 2) {
        sendMessage(Protocol::buildResponse(false, "参数无效"));
        return;
    }
    
    const std::string& inviter = params[0];
    const std::string& response = params[1];
    
    // 检查是否有待处理的邀请
    if (m_pendingInviter.empty() || m_pendingInviter != inviter) {
        sendMessage(Protocol::buildResponse(false, "没有来自该玩家的待处理邀请"));
        return;
    }
    
    bool accept = (response == "yes");  // 客户端发送 "yes" 或 "no"
    m_pendingInviter.clear();
    
    m_server->getLobby()->handleInviteResponse(inviter, m_username, accept);
}

void ClientHandler::handleBattleAction(const std::vector<std::string>& params) {
    if (params.size() < 2) {
        sendMessage(Protocol::buildResponse(false, "Invalid parameters"));
        return;
    }
    
    if (m_state != ClientState::InBattle) {
        sendMessage(Protocol::buildResponse(false, "You are not in battle"));
        return;
    }
    
    int skillIndex = std::atoi(params[0].c_str());
    const std::string& targetName = params[1];
    
    bool success = m_server->getBattleManager()->handleBattleAction(
        m_battleRoomId, m_username, skillIndex, targetName);
    
    if (!success) {
        sendMessage(Protocol::buildResponse(false, "Invalid action"));
    }
}

void ClientHandler::handleLogout() {
    std::cout << "User " << m_username << " logging out" << std::endl;
    m_isRunning = false;
}
