#include "client/GameClient.h"
#include "common/Protocol.h"
#include <iostream>
#include <sstream>
#include <thread>
#include <chrono>

GameClient::GameClient(const std::string& serverAddress, int serverPort)
    : m_serverAddress(serverAddress),
      m_serverPort(serverPort),
      m_isRunning(false),
      m_isConnected(false),
      m_isAuthenticated(false),
      m_inBattle(false),
      m_waitingForTurn(false) {
}

GameClient::~GameClient() {
    disconnect();
}

bool GameClient::connect() {
    if (!m_socket.create()) {
        std::cerr << "创建socket失败" << std::endl;
        return false;
    }
    
    if (!m_socket.connect(m_serverAddress, m_serverPort)) {
        std::cerr << "连接服务器失败" << std::endl;
        return false;
    }
    
    m_isConnected = true;
    m_isRunning = true;
    
    // 启动接收线程
    m_recvThread = std::thread(&GameClient::recvLoop, this);
    
    std::cout << "成功连接到服务器！" << std::endl;
    return true;
}

void GameClient::disconnect() {
    if (!m_isRunning) {
        return;
    }
    
    m_isRunning = false;
    m_socket.close();
    
    if (m_recvThread.joinable()) {
        m_recvThread.join();
    }
    
    std::cout << "已断开与服务器的连接" << std::endl;
}

void GameClient::run() {
    if (!connect()) {
        return;
    }
    
    try {
        while (m_isRunning && m_isConnected) {
            if (!m_isAuthenticated) {
                showMainMenu();
            } else if (m_inBattle && m_waitingForTurn) {
                // 只在战斗中且轮到玩家时才显示战斗菜单
                showBattleMenu();
            } else if (!m_inBattle) {
                // 不在战斗中，显示大厅菜单
                showLobbyMenu();
            } else {
                // 在战斗中但不是玩家回合，等待
                std::this_thread::sleep_for(std::chrono::milliseconds(100));
            }
        }
    } catch (const std::exception& e) {
        std::cerr << "主循环异常: " << e.what() << std::endl;
    } catch (...) {
        std::cerr << "主循环未知异常" << std::endl;
    }
}

bool GameClient::sendMessage(const std::string& message) {
    return m_socket.send(message);
}

void GameClient::recvLoop() {
    try {
        while (m_isRunning) {
            std::string message = m_socket.recvLine();
            if (message.empty()) {
                if (m_isRunning) {
                    std::cerr << "\n连接已断开" << std::endl;
                    m_isConnected = false;
                    m_isRunning = false;
                }
                break;
            }
            
            handleServerMessage(message);
        }
    } catch (const std::exception& e) {
        std::cerr << "\n接收线程异常: " << e.what() << std::endl;
        m_isConnected = false;
        m_isRunning = false;
    } catch (...) {
        std::cerr << "\n接收线程未知异常" << std::endl;
        m_isConnected = false;
        m_isRunning = false;
    }
}

void GameClient::handleServerMessage(const std::string& message) {
    std::string command;
    std::vector<std::string> params;
    
    if (!Protocol::parseMessage(message, command, params)) {
        std::cerr << "解析服务器消息失败" << std::endl;
        return;
    }
    
    if (command == Protocol::S2C_RESPONSE) {
        if (params.size() >= 2) {
            std::cout << "\n[服务器] " << params[1] << std::endl;
            showPrompt();
        }
    } else if (command == Protocol::S2C_LOGIN_OK) {
        if (params.size() >= 5) {
            m_username = params[0];
            m_isAuthenticated = true;
            std::cout << "\n【登录成功】" << std::endl;
            std::cout << "欢迎，" << params[0] << "！" << std::endl;
            std::cout << "职业：" << params[1] << "，等级：" << params[2] << std::endl;
            std::cout << "生命值：" << params[3] << "，魔法值：" << params[4] << std::endl;
            showPrompt();
        }
    } else if (command == Protocol::S2C_MSG) {
        if (params.size() >= 2) {
            std::cout << "\n【聊天】" << params[0] << "：" << params[1] << std::endl;
            showPrompt();
        }
    } else if (command == Protocol::S2C_LIST_PLAYERS) {
        if (!params.empty()) {
            std::cout << "\n【在线玩家】：" << params[0] << std::endl;
        } else {
            std::cout << "\n【在线玩家】：（无）" << std::endl;
        }
        showPrompt();
    } else if (command == Protocol::S2C_INVITE) {
        if (!params.empty()) {
            std::cout << "\n*** " << params[0] << " 邀请你战斗！***" << std::endl;
            std::cout << "输入 'accept " << params[0] << "' 接受，或 'reject " << params[0] << "' 拒绝" << std::endl;
            showPrompt();
        }
    } else if (command == Protocol::S2C_INVITE_RESULT) {
        if (params.size() >= 2) {
            std::cout << "\n【邀请】" << params[0] << " " << params[1] << " 了你的邀请" << std::endl;
            showPrompt();
        }
    } else if (command == Protocol::S2C_BATTLE_START) {
        m_inBattle = true;
        if (params.size() >= 2) {
            std::cout << "\n*** 战斗开始！***" << std::endl;
            std::cout << "对手：" << params[0] << "（" << params[1] << "）" << std::endl;
            std::cout << "====================" << std::endl;
            showPrompt();
        }
    } else if (command == Protocol::S2C_BATTLE_TURN) {
        if (!params.empty()) {
            if (params[0] == "YOUR_TURN") {
                std::cout << "\n>>> 你的回合 <<<" << std::endl;
                std::cout << "输入 'attack' 使用普通攻击" << std::endl;
                m_waitingForTurn = true;
                showPrompt();
            } else {
                std::cout << "\n>>> 对手的回合..." << std::endl;
                m_waitingForTurn = false;
            }
        }
    } else if (command == Protocol::S2C_BATTLE_LOG) {
        if (!params.empty()) {
            std::cout << "【战斗】" << params[0] << std::endl;
        }
    } else if (command == Protocol::S2C_BATTLE_END) {
        m_inBattle = false;
        m_waitingForTurn = false;
        
        if (!params.empty()) {
            std::cout << "\n*** 战斗结束！***" << std::endl;
            if (params[0] == "WIN") {
                std::cout << "你赢了！恭喜！" << std::endl;
            } else if (params[0] == "LOSE") {
                std::cout << "你输了。下次加油！" << std::endl;
            } else {
                std::cout << "平局！" << std::endl;
            }
            std::cout << "====================" << std::endl;
            showPrompt();
        }
    } else if (command == Protocol::S2C_SYSTEM) {
        if (!params.empty()) {
            std::cout << "\n[System] " << params[0] << std::endl;
            showPrompt();
        }
    }
}

void GameClient::showMainMenu() {
    printTitle("主菜单");
    std::cout << "1. 注册" << std::endl;
    std::cout << "2. 登录" << std::endl;
    std::cout << "3. 退出" << std::endl;
    printSeparator();
    showPrompt();
    
    std::string input;
    std::getline(std::cin, input);
    
    if (input == "1") {
        handleRegister();
    } else if (input == "2") {
        handleLogin();
    } else if (input == "3") {
        disconnect();
    }
}

void GameClient::showLobbyMenu() {
    printTitle("游戏大厅");
    std::cout << "1. 聊天" << std::endl;
    std::cout << "2. 查看在线玩家" << std::endl;
    std::cout << "3. 邀请战斗" << std::endl;
    std::cout << "4. 查看战斗状态" << std::endl;
    std::cout << "5. 登出" << std::endl;
    printSeparator();
    
    std::string input;
    showPrompt();
    std::getline(std::cin, input);
    
    // 检查状态是否在输入期间改变（例如收到战斗邀请被接受）
    if (m_inBattle) {
        return;  // 已进入战斗，不处理大厅输入
    }
    
    handleLobbyInput(input);
}

void GameClient::showBattleMenu() {
    printTitle("战斗中");
    std::cout << "输入 'attack' 或 '攻击' 使用普通攻击" << std::endl;
    printSeparator();
    
    std::string input;
    showPrompt();
    std::getline(std::cin, input);
    
    // 检查状态是否在输入期间改变
    if (!m_inBattle || !m_waitingForTurn) {
        return;  // 状态已改变，不处理输入
    }
    
    handleBattleInput(input);
}

void GameClient::handleRegister() {
    std::string username, password;
    std::cout << "用户名：";
    std::getline(std::cin, username);
    std::cout << "密码：";
    std::getline(std::cin, password);
    
    std::string msg = Protocol::buildMessage(Protocol::C2S_REGISTER, {username, password});
    sendMessage(msg);
}

void GameClient::handleLogin() {
    std::string username, password;
    std::cout << "用户名：";
    std::getline(std::cin, username);
    std::cout << "密码：";
    std::getline(std::cin, password);
    
    std::string msg = Protocol::buildMessage(Protocol::C2S_LOGIN, {username, password});
    sendMessage(msg);
}

void GameClient::handleLobbyInput(const std::string& input) {
    if (input.empty()) {
        return;
    }
    
    // 检查是否是邀请响应命令（accept 或 reject）
    if (input.find("accept ") == 0 || input.find("reject ") == 0) {
        size_t spacePos = input.find(' ');
        if (spacePos != std::string::npos) {
            std::string response = input.substr(0, spacePos);  // "accept" 或 "reject"
            std::string inviter = input.substr(spacePos + 1);  // 邀请者用户名
            
            bool accept = (response == "accept");
            std::string msg = Protocol::buildMessage(Protocol::C2S_INVITE_RSP, {inviter, accept ? "yes" : "no"});
            sendMessage(msg);
        }
        return;
    }
    
    if (input == "1") {
        // Chat
        std::cout << "消息：";
        std::string message;
        std::getline(std::cin, message);
        if (!message.empty()) {
            std::string msg = Protocol::buildMessage(Protocol::C2S_CHAT, {message});
            sendMessage(msg);
        }
    } else if (input == "2") {
        // List players
        std::string msg = Protocol::buildMessage(Protocol::C2S_LIST_PLAYERS);
        sendMessage(msg);
    } else if (input == "3") {
        // Invite to battle
        std::cout << "目标玩家用户名：";
        std::string target;
        std::getline(std::cin, target);
        if (!target.empty()) {
            std::string msg = Protocol::buildMessage(Protocol::C2S_INVITE, {target});
            sendMessage(msg);
        }
    } else if (input == "4") {
        // Check battle status
        std::cout << "战斗状态：" << (m_inBattle ? "战斗中" : "未在战斗") << std::endl;
    } else if (input == "5") {
        // Logout
        std::string msg = Protocol::buildMessage(Protocol::C2S_LOGOUT);
        sendMessage(msg);
        m_isAuthenticated = false;
        m_username.clear();
    } else {
        std::cout << "无效选项。请输入1-5。" << std::endl;
    }
}

void GameClient::handleBattleInput(const std::string& input) {
    if (input.empty()) {
        return;
    }
    
    if (input == "attack" || input == "攻击") {
        // 简化版：总是攻击对手（skillIndex=0, target=对手名）
        std::string msg = Protocol::buildMessage(Protocol::C2S_BATTLE_ACTION, {"0", "opponent"});
        sendMessage(msg);
        m_waitingForTurn = false;
    } else {
        std::cout << "无效命令。请输入 'attack' 或 '攻击'" << std::endl;
    }
}

void GameClient::showPrompt() {
    if (m_inBattle) {
        std::cout << "【战斗】> " << std::flush;
    } else if (m_isAuthenticated) {
        std::cout << "【" << m_username << "】> " << std::flush;
    } else {
        std::cout << "> " << std::flush;
    }
}

void GameClient::clearScreen() {
    #ifdef _WIN32
        system("cls");
    #else
        system("clear");
    #endif
}

void GameClient::printSeparator() {
    std::cout << "================================" << std::endl;
}

void GameClient::printTitle(const std::string& title) {
    printSeparator();
    std::cout << "  " << title << std::endl;
    printSeparator();
}
