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

#include "misc/Time.h"

#include <iostream>

#ifdef NDEBUG
#define MIN_PLAYER_WAITING 2
#else
#define MIN_PLAYER_WAITING 1
#endif

namespace td {
namespace server {

/*static constexpr std::uint8_t timeNotifications[] = {
    2 * 60, // 2 min
    60 + 30, // 1 min 30 s
    60, // 1 min
    30, // 30 s
    15, // 15 s
    10, // 10 s
    5, // 5 s
    4, // 4 s
    3, // 3 s
    2, // 2 s
    1, // 1 s
};*/

Lobby::Lobby(Server* server) : m_Server(server), m_Timer(1000, std::bind(&Lobby::sendTimeRemaining, this)) {

}

void Lobby::tick() {
    if (m_GameStarted || m_StartTimerTime == 0)
        return;

    if (utils::getTime() - m_StartTimerTime >= LobbyWaitingTime) {
        protocol::UpdateGameStatePacket packet(game::GameState::Game);
        m_Server->broadcastPacket(&packet);
        m_GameStarted = true;
        m_Server->lauchGame();
        return;
    }

    m_Timer.update();
}

void Lobby::sendTimeRemaining() {
    protocol::UpdateLobbyTimePacket packet(LobbyWaitingTime - (utils::getTime() - m_StartTimerTime)); // converting second to millis
    m_Server->broadcastPacket(&packet);
}

void Lobby::OnPlayerJoin(std::uint8_t playerID) {
    if (m_GameStarted)
        return;
    std::cout << "(Server) Player Joined Lobby !\n";
    m_Players.push_back(playerID);
    if (m_Players.size() == MIN_PLAYER_WAITING) { // start timer if a second player join the match
        m_StartTimerTime = utils::getTime();
        m_Timer.reset();
        sendTimeRemaining();
    }
}

void Lobby::OnPlayerLeave(std::uint8_t playerID) {
    if (m_GameStarted)
        return;
    std::cout << "(Server) Player Leaved Lobby !\n";
    auto it = std::find(m_Players.begin(), m_Players.end(), playerID);
    if (it == m_Players.end())
        return;
    m_Players.erase(it);
    if (m_Players.size() == 1) {
        protocol::UpdateLobbyTimePacket packet(0);
        m_Server->broadcastPacket(&packet);
        m_StartTimerTime = 0; // reset timer if there is only one player left
    }
}

} // namespace server
} // namespace td
