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

GameServer::GameServer(int port, const std::string& dbPath)
    : m_port(port), m_nextClientId(1), m_isRunning(false) {
    
    // 初始化数据库
    m_database = std::make_shared<Database>(dbPath);
    
    // 初始化游戏模块
    m_lobby = std::make_shared<GameLobby>(this);
    m_battleManager = std::make_shared<BattleRoomManager>(this);
}

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

bool GameServer::start() {
    if (!m_database->isOpen()) {
        std::cerr << "无法打开数据库" << std::endl;
        return false;
    }
    
    // 创建并绑定服务器socket
    if (!m_serverSocket.create()) {
        std::cerr << "创建服务器socket失败" << std::endl;
        return false;
    }
    
    if (!m_serverSocket.bind("0.0.0.0", m_port)) {
        std::cerr << "绑定端口失败：" << m_port << std::endl;
        return false;
    }
    
    if (!m_serverSocket.listen(10)) {
        std::cerr << "监听端口失败：" << m_port << std::endl;
        return false;
    }
    
    m_isRunning = true;
    
    std::cout << "服务器启动成功" << std::endl;
    std::cout << "监听端口：" << m_port << std::endl;
    std::cout << "数据库：" << (m_database->isOpen() ? "已连接" : "失败") << std::endl;
    
    return true;
}

void GameServer::stop() {
    if (!m_isRunning) {
        return;
    }
    
    m_isRunning = false;
    std::cout << "正在停止服务器..." << std::endl;
    
    // 停止所有客户端
    {
        std::lock_guard<std::mutex> lock(m_clientsMutex);
        for (auto& pair : m_clients) {
            pair.second->stop();
        }
        m_clients.clear();
    }
    
    // 关闭服务器socket
    m_serverSocket.close();
    
    std::cout << "服务器已停止" << std::endl;
}

void GameServer::run() {
    std::cout << "服务器正在接受连接..." << std::endl;
    
    while (m_isRunning) {
        std::string clientAddr;
        int clientPort;
        SocketFd clientFd = m_serverSocket.accept(clientAddr, clientPort);
        
        if (clientFd < 0) {
            if (m_isRunning) {
                std::cerr << "接受客户端连接失败" << std::endl;
            }
            continue;
        }
        
        std::cout << "客户端已连接，来自 " << clientAddr << ":" << clientPort << std::endl;
        
        // 创建ClientHandler
        int clientId = m_nextClientId++;
        
        auto handler = std::make_shared<ClientHandler>(clientId, clientFd, this);
        
        // 添加到客户端列表
        {
            std::lock_guard<std::mutex> lock(m_clientsMutex);
            m_clients[clientId] = handler;
        }
        
        // 启动处理线程
        handler->start();
        
        std::cout << "新客户端已连接：ID=" << clientId << "，FD=" << clientFd << std::endl;
    }
}

int GameServer::addClient(std::shared_ptr<ClientHandler> client) {
    std::lock_guard<std::mutex> lock(m_clientsMutex);
    int clientId = m_nextClientId++;
    m_clients[clientId] = client;
    return clientId;
}

void GameServer::removeClient(int clientId) {
    std::lock_guard<std::mutex> lock(m_clientsMutex);
    auto it = m_clients.find(clientId);
    if (it != m_clients.end()) {
        std::cout << "Removing client: ID=" << clientId << std::endl;
        m_clients.erase(it);
    }
}

std::shared_ptr<ClientHandler> GameServer::getClientByUsername(const std::string& username) {
    std::lock_guard<std::mutex> lock(m_clientsMutex);
    for (auto& pair : m_clients) {
        if (pair.second->getUsername() == username) {
            return pair.second;
        }
    }
    return nullptr;
}

std::vector<std::string> GameServer::getOnlinePlayers() {
    std::vector<std::string> players;
    std::lock_guard<std::mutex> lock(m_clientsMutex);
    
    for (const auto& pair : m_clients) {
        const std::string& username = pair.second->getUsername();
        if (!username.empty() && pair.second->getState() == ClientState::Lobby) {
            players.push_back(username);
        }
    }
    
    return players;
}

void GameServer::broadcastToLobby(const std::string& message, int excludeClientId) {
    std::lock_guard<std::mutex> lock(m_clientsMutex);
    
    for (auto& pair : m_clients) {
        if (pair.first != excludeClientId && 
            pair.second->getState() == ClientState::Lobby) {
            pair.second->sendMessage(message);
        }
    }
}
