#include "game/server/ServerGame.h"
#include "game/server/Server.h"

namespace td {
namespace server {

ServerGame::ServerGame(server::Server* server) : game::Game(&m_ServerWorld), m_Server(server), m_ServerWorld(server, this) {

}

void ServerGame::tick(std::uint64_t delta) {
    if (m_GameState == game::GameState::Game) {
        Game::tick(delta);
        updatePlayerStats();
    }
}

void ServerGame::startGame() {
    balanceTeams();

    protocol::WorldBeginDataPacket headerMapData(m_World);
    m_Server->broadcastPacket(&headerMapData);

    protocol::WorldDataPacket mapData(m_World);
    m_Server->broadcastPacket(&mapData);

    m_GameState = game::GameState::Game;
}

void ServerGame::updatePlayerStats() {
    m_GoldMineTimer.update();
    for (auto& pair : m_Server->getPlayers()) {
        game::Player& player = pair.second;
        if (player.hasGoldChanged()) {
            protocol::UpdateMoneyPacket packet(player.getGold());
            m_Server->getConnexions()[player.getID()].sendPacket(&packet);
            player.updateGold();
        }
        if (player.hasExpChanged()) {
            protocol::UpdateExpPacket packet(player.getExp());
            m_Server->getConnexions()[player.getID()].sendPacket(&packet);
            player.updateExp();
        }
    }
}

void ServerGame::updateGoldMines() {
    for (auto& pair : m_Server->getPlayers()) {
        game::Player* player = &pair.second;
        player->addGold(player->getGoldPerSecond());
    }
}

void ServerGame::balanceTeams() {
    for (auto& playerInfo : Game::m_Players) {
        game::Player& player = playerInfo.second;
        if (player.getTeamColor() == game::TeamColor::None) {
            game::Team& redTeam = getRedTeam();
            game::Team& blueTeam = getBlueTeam();
            if (blueTeam.getPlayerCount() > redTeam.getPlayerCount()) {
                player.setTeamColor(game::TeamColor::Red);
                redTeam.addPlayer(&player);
            } else {
                player.setTeamColor(game::TeamColor::Blue);
                blueTeam.addPlayer(&player);
            }
            protocol::UpdatePlayerTeamPacket packet(player.getID(), player.getTeamColor());
            m_Server->broadcastPacket(&packet);
        }
    }
}

} // namespace game
} // namespace td
