#include "render/gui/GameMenu.h"
#include "render/gui/imgui/imgui.h"

#include "render/WorldRenderer.h"

#include "game/client/Client.h"
#include "game/server/Lobby.h"

namespace td {
namespace gui {

GameMenu::GameMenu(client::Client* client) : GuiWidget(client), m_SummonMenu(std::make_unique<SummonMenu>(client)) {

}

void GameMenu::render() {
    if (getClient()->getGame().getGameState() == td::game::GameState::Lobby) {
        ImGui::Begin("Lobby");

        showTPS();
        showPlayers();
        showLobbyProgress();
        showTeamSelection();

        ImGui::End();
    }
    if (getClient()->getGame().getGameState() == td::game::GameState::Game) {
        ImGui::Begin("Game");

        showTPS();
        showStats();
        showPlayers();

        ImGui::End();

        m_SummonMenu->render();
    }
}

void GameMenu::showPlayers() {
    if (ImGui::TreeNode(std::string("Players (" + std::to_string(getClient()->getGame().getPlayers().size()) + ")##player_list").c_str())) {
        for (auto pair : getClient()->getGame().getPlayers()) {
            const td::game::Player& player = pair.second;
            ImGui::PushStyleColor(ImGuiCol_Text, render::WorldRenderer::getImGuiTeamColor(player.getTeamColor()));
            ImGui::Text("%s", player.getName().c_str());
            ImGui::PopStyleColor();
        }
        ImGui::TreePop();
    }
}

void GameMenu::showTeamSelection() {
    if (getClient()->getGame().getPlayer() == nullptr)
        return;
    td::game::TeamColor playerTeam = getClient()->getGame().getPlayer()->getTeamColor();

    if (ImGui::Button(std::string((playerTeam == td::game::TeamColor::Red ? "Leave" : "Join") + std::string(" Red Team")).c_str())) {
        if (playerTeam == td::game::TeamColor::Red)
            getClient()->selectTeam(td::game::TeamColor::None);
        else
            getClient()->selectTeam(td::game::TeamColor::Red);
    }
    ImGui::SameLine();
    if (ImGui::Button(std::string((playerTeam == td::game::TeamColor::Blue ? "Leave" : "Join") + std::string(" Blue Team")).c_str())) {
        if (playerTeam == td::game::TeamColor::Blue)
            getClient()->selectTeam(td::game::TeamColor::None);
        else
            getClient()->selectTeam(td::game::TeamColor::Blue);
    }
}

void GameMenu::showLobbyProgress() {
    const int timePassed = server::Lobby::LobbyWaitingTime - getClient()->getGame().getLobbyTime();
    const float progress = (float)timePassed / (float)(server::Lobby::LobbyWaitingTime);
    if (progress > 0 && progress < 1) {
        ImGui::ProgressBar(progress, ImVec2(0.0f, 0.0f), std::string(std::to_string(getClient()->getGame().getLobbyTime() / 1000) + "s").c_str());
        ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
        ImGui::Text("Time Remaining");
    } else {
        ImGui::Text("Waiting for players ...\n");
    }
}

void GameMenu::showTPS() {
    ImGui::Text("Server TPS : %.1f", getClient()->getConnexion().getServerTPS());
    ImGui::Text("Server Ping : %i", getClient()->getConnexion().getServerPing());
}

void GameMenu::showStats() {
    ImGui::Text("Gold : %i", getClient()->getGame().getPlayer()->getGold());
    ImGui::Text("EXP: %i", getClient()->getGame().getPlayer()->getExp());
}

} // namespace gui
} // namespace td
