#include "server/BattleRoom.h"
#include "server/ClientHandler.h"
#include "common/Protocol.h"
#include "core/Skills.h"
#include <iostream>
#include <sstream>

BattleRoom::BattleRoom(int roomId,
                      std::shared_ptr<ClientHandler> player1,
                      std::shared_ptr<ClientHandler> player2,
                      std::shared_ptr<ICharacter> char1,
                      std::shared_ptr<ICharacter> char2)
    : m_roomId(roomId),
      m_player1(player1),
      m_player2(player2),
      m_char1(char1),
      m_char2(char2),
      m_isRunning(false),
      m_currentTurn(0),
      m_turnCount(0) {
}

BattleRoom::~BattleRoom() {
    if (m_isRunning) {
        endBattle();
    }
}

void BattleRoom::start() {
    std::lock_guard<std::mutex> lock(m_mutex);
    
    if (m_isRunning) {
        return;
    }
    
    m_isRunning = true;
    m_turnCount = 0;
    
    // 根据速度决定谁先手
    m_currentTurn = (m_char1->getSpeed() >= m_char2->getSpeed()) ? 0 : 1;
    
    // 发送战斗开始消息
    std::string startLog = "战斗开始：" + m_char1->getName() + " vs " + m_char2->getName();
    addLog(startLog);
    
    // 通知双方战斗开始
    std::string msg1 = Protocol::buildMessage(Protocol::S2C_BATTLE_START, 
        {m_char2->getName(), "Mage"});  // 简化：对手信息
    std::string msg2 = Protocol::buildMessage(Protocol::S2C_BATTLE_START, 
        {m_char1->getName(), "Warrior"});
    
    sendToPlayer1(msg1);
    sendToPlayer2(msg2);
    
    // 发送初始回合通知
    notifyTurn();
    sendBattleStatus();
    
    std::cout << "战斗 " << m_roomId << " 已开始：" << startLog << std::endl;
}

bool BattleRoom::handleAction(const std::string& username, 
                             int skillIndex, 
                             const std::string& targetName) {
    std::lock_guard<std::mutex> lock(m_mutex);
    
    std::cout << "[DEBUG] handleAction called: user=" << username 
              << " skillIndex=" << skillIndex 
              << " target=" << targetName << std::endl;
    
    if (!m_isRunning) {
        std::cout << "[DEBUG] Battle not running!" << std::endl;
        return false;
    }
    
    // 检查是否轮到该玩家
    if (!isPlayerTurn(username)) {
        std::cout << "[DEBUG] Not player's turn! Current turn: " << m_currentTurn << std::endl;
        return false;
    }
    
    std::cout << "[DEBUG] Executing action..." << std::endl;
    
    // 确定攻击者和防守者
    ICharacter* attacker = (m_currentTurn == 0) ? m_char1.get() : m_char2.get();
    ICharacter* defender = (m_currentTurn == 0) ? m_char2.get() : m_char1.get();
    
    // 获取技能（简化版：使用skillIndex，0=普通攻击）
    ISkill* skill = nullptr;
    if (skillIndex == 0) {
        skill = attacker->getSkill("NormalAttack");
    } else if (skillIndex == 1) {
        // 获取第二个技能
        skill = (m_currentTurn == 0) ? 
            (m_char1->getSkill("HeavyStrike") ? m_char1->getSkill("HeavyStrike") : m_char1->getSkill("Fireball")) :
            (m_char2->getSkill("HeavyStrike") ? m_char2->getSkill("HeavyStrike") : m_char2->getSkill("Fireball"));
    }
    
    if (!skill) {
        std::cerr << "[ERROR] Skill not found for skillIndex " << skillIndex 
                  << " for character " << attacker->getName() 
                  << ". Falling back to NormalAttack." << std::endl;
        skill = attacker->getSkill("NormalAttack");
    }

    // 最终检查，如果连普通攻击都没有，就无法继续
    if (!skill) {
        std::cerr << "[FATAL] Critical error: NormalAttack skill is missing for character " 
                  << attacker->getName() << ". Cannot proceed with action." << std::endl;
        // 在这种严重错误下，也许应该结束战斗或通知玩家
        broadcastToBoth(Protocol::buildBattleLog("错误：攻击失败，找不到技能！"));
        return false; // 提前退出，防止崩溃
    }
    
    // 执行技能
    int defenderHpBefore = defender->getHp();
    skill->execute(*attacker, *defender);
    int defenderHpAfter = defender->getHp();
    int damage = defenderHpBefore - defenderHpAfter;
    
    // 记录战斗日志
    std::ostringstream logStream;
    logStream << attacker->getName() << " 使用 " << skill->getName() 
              << " 攻击 " << defender->getName() << "，造成 " << damage << " 点伤害！";
    std::string actionLog = logStream.str();
    addLog(actionLog);
    
    // 广播战斗日志
    broadcastToBoth(Protocol::buildBattleLog(actionLog));
    
    // 发送状态更新
    sendBattleStatus();
    
    // 检查战斗是否结束
    if (isFinished()) {
        endBattle();
        return true;
    }
    
    // 切换回合
    m_currentTurn = (m_currentTurn == 0) ? 1 : 0;
    m_turnCount++;
    
    // 通知下一回合
    notifyTurn();
    
    return true;
}

bool BattleRoom::isFinished() const {
    return !m_char1->isAlive() || !m_char2->isAlive() || m_turnCount >= 50;
}

std::string BattleRoom::getWinner() const {
    if (m_char1->isAlive() && !m_char2->isAlive()) {
        return m_char1->getName();
    } else if (m_char2->isAlive() && !m_char1->isAlive()) {
        return m_char2->getName();
    }
    return "";  // 平局或未结束
}

std::vector<std::string> BattleRoom::getBattleLog() const {
    return m_historyLog.getAllEntries();
}

bool BattleRoom::isPlayerTurn(const std::string& username) const {
    if (m_currentTurn == 0) {
        return username == m_player1->getUsername();
    } else {
        return username == m_player2->getUsername();
    }
}

void BattleRoom::executeTurn() {
    // 这个方法在简化版本中不使用，由handleAction处理
}

void BattleRoom::broadcastToBoth(const std::string& message) {
    sendToPlayer1(message);
    sendToPlayer2(message);
}

void BattleRoom::sendToPlayer1(const std::string& message) {
    if (m_player1) {
        m_player1->sendMessage(message);
    }
}

void BattleRoom::sendToPlayer2(const std::string& message) {
    if (m_player2) {
        m_player2->sendMessage(message);
    }
}

void BattleRoom::addLog(const std::string& log) {
    m_historyLog.add(log);
}

void BattleRoom::endBattle() {
    if (!m_isRunning) {
        return;
    }
    
    m_isRunning = false;
    
    std::string winner = getWinner();
    std::string endLog;
    
    if (!winner.empty()) {
        endLog = winner + " 获胜！";
        
        // 通知胜负
        if (winner == m_player1->getUsername()) {
            sendToPlayer1(Protocol::buildMessage(Protocol::S2C_BATTLE_END, {"WIN"}));
            sendToPlayer2(Protocol::buildMessage(Protocol::S2C_BATTLE_END, {"LOSE"}));
        } else {
            sendToPlayer1(Protocol::buildMessage(Protocol::S2C_BATTLE_END, {"LOSE"}));
            sendToPlayer2(Protocol::buildMessage(Protocol::S2C_BATTLE_END, {"WIN"}));
        }
    } else {
        endLog = "战斗以平局结束！";
        broadcastToBoth(Protocol::buildMessage(Protocol::S2C_BATTLE_END, {"DRAW"}));
    }
    
    addLog(endLog);
    broadcastToBoth(Protocol::buildBattleLog(endLog));
    
    // 重置玩家状态
    m_player1->setState(ClientState::Lobby);
    m_player1->setBattleRoomId(-1);
    m_player2->setState(ClientState::Lobby);
    m_player2->setBattleRoomId(-1);
    
    std::cout << "战斗 " << m_roomId << " 已结束：" << endLog << std::endl;
}

void BattleRoom::notifyTurn() {
    if (m_currentTurn == 0) {
        sendToPlayer1(Protocol::buildMessage(Protocol::S2C_BATTLE_TURN, {"YOUR_TURN"}));
        sendToPlayer2(Protocol::buildMessage(Protocol::S2C_BATTLE_TURN, {"OPP_TURN"}));
    } else {
        sendToPlayer1(Protocol::buildMessage(Protocol::S2C_BATTLE_TURN, {"OPP_TURN"}));
        sendToPlayer2(Protocol::buildMessage(Protocol::S2C_BATTLE_TURN, {"YOUR_TURN"}));
    }
}

void BattleRoom::sendBattleStatus() {
    std::ostringstream status;
    status << m_char1->getName() << " HP:" << m_char1->getHp() 
           << " | " << m_char2->getName() << " HP:" << m_char2->getHp();
    
    std::string statusMsg = status.str();
    addLog(statusMsg);
    broadcastToBoth(Protocol::buildBattleLog(statusMsg));
}
