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

#include "td/protocol/packets/UpdateLobbyTimePacket.h"

#include "td/misc/Time.h"

#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::OpenLobby() {
	m_LobbyOpened = true;
	m_StartTimerTime = 0;

	if (m_Players.size() >= MIN_PLAYER_WAITING) { // start timer if a enough players are here
		m_StartTimerTime = utils::GetTime();
		m_Timer.Reset();
		SendTimeRemaining();
	}
}

void Lobby::Tick() {
	if (!m_LobbyOpened || m_StartTimerTime == 0)
		return;

	if (utils::GetTime() - m_StartTimerTime >= LobbyWaitingTime) {
		m_Server->GetGame().NotifyListeners(&game::GameListener::OnGameBegin);
		m_LobbyOpened = false;
		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) {
	m_Players.push_back(playerID);

	if (!m_LobbyOpened)
		return;
	
	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)
{
	auto it = std::find(m_Players.begin(), m_Players.end(), playerID);
	if (it == m_Players.end())
		return;

	m_Players.erase(it);

	if (!m_LobbyOpened)
		return;

	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
