// Project Lab - NHTV Igad

#include "UnrealProject.h"
#include "LobbySlot.h"
#include "LobbyPlayerSlot.h"
#include "PlayerStateBase.h"
#include "PlayerControllerBase.h"

#include "SubMenu.h"
#include "MenuScreenBase.h"
#include "GameStateBase.h"

ULobbySlot::ULobbySlot(const FObjectInitializer& init)
	: Super(init)
{
}

void ULobbySlot::NativeConstruct()
{
	Super::NativeConstruct();
	m_open = false;
}
void ULobbySlot::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
	Super::NativeTick(MyGeometry, InDeltaTime);
	this->bIsEnabled = m_open;
}

void ULobbySlot::SetTeamIndex(uint32 idx)
{
	m_teamIndex = idx;
	m_UpdateTeamTitle();
}
void ULobbySlot::m_UpdateTeamTitle()
{
	// Set the title of this team slot
	if (m_teamName)
	{
		std::wstring teamName = std::wstring() + L"Team " + m_teamIndex + L" (" + m_players.Num() + L"/2)";
		SetButtonText(FString(teamName.c_str()));
	}
}

void ULobbySlot::UpdatePlayers(TArray<APlayerStateBase*> players)
{
	check(m_playerList);
	check(m_playerSlots.Num() == 2);

	UWorld* const world = GetWorld();
	check(world);
	APlayerControllerBase* player = Cast<APlayerControllerBase>(world->GetGameInstance()->GetFirstLocalPlayerController());
	check(player);
	APlayerStateBase* myState = Cast<APlayerStateBase>(player->PlayerState);

	// Set all the player slots in this team to show their respective player / no player placeholder
	m_players = players;
	for (int32 i = 0; i < 2; i++)
	{
		if (i < m_players.Num())
		{
			APlayerStateBase* player = players[i];
			m_playerSlots[i]->Init(player, player == myState);
		}
		else
		{
			m_playerSlots[i]->Init(nullptr);
		}
	}
	m_UpdateTeamTitle();
}
bool ULobbySlot::OnSlotSelected()
{
	UWorld* const world = GetWorld();
	check(world);
	APlayerControllerBase* player = Cast<APlayerControllerBase>(world->GetGameInstance()->GetFirstLocalPlayerController());
	check(player);
	APlayerStateBase* myState = Cast<APlayerStateBase>(player->PlayerState);

	AGameStateBase* gameState = Cast<AGameStateBase>(world->GetGameState());

	if (myState->GetReadyState())
		return false;

	if (gameState)
	{
		auto pbt = gameState->GetPlayersByTeam();
		if (m_teamIndex < (uint32)pbt.Num() && pbt[m_teamIndex].Num() == 2)
		{
			return false;
		}
	}

	// Try for the local player to join this team
	if (myState) // Check the state cause it can be null
		myState->RequestTeamEntry(m_teamIndex);
	else
		GWERROR(L"Player not set in " + GetName());

	// Make sure this item is now selected
	GetSubMenu()->SelectNewItem(this);

	return true;
}

void ULobbySlot::Init(UTextBlock* teamName, UVerticalBox* playerList)
{
	m_teamName = teamName;
	m_playerList = playerList;

	// Add fixed 2 player slots to this team
	m_playerList->ClearChildren();
	for (int32 i = 0; i < 2; i++)
	{
		ULobbyPlayerSlot* playerSlot = CreateWidget<ULobbyPlayerSlot>(GetWorld(), lobbyPlayerSlotClass);
		check(playerSlot);
		playerSlot->Init(nullptr);
		m_playerSlots.Add(playerSlot);
		m_playerList->AddChild(playerSlot);
	}
}

void ULobbySlot::SetState(bool open)
{
	m_open = open;
}
