// Project Lab - NHTV Igad

#include "UnrealProject.h"
#include "ScoreBoardSlot.h"
#include "DefaultPlayerState.h"
#include "GameStateBase.h"
#include "TeamData.h"
#include "ScoreBoard.h"


UScoreBoard::UScoreBoard(const FObjectInitializer& init) : Super(init)
{
	teamData = ConstructorHelpers::FObjectFinder<UTeamData>(TEXT("/Game/Assets/TeamData")).Object;
}

void UScoreBoard::Init(UVerticalBox* container)
{
	m_container = container;

	// Precreate the widgets so that we can utilize them later
	if (IsValid(scoreBoardSlot) && IsValid(m_container))
	{
		for (int32 i = 0; i < 8; i++)
		{
			UScoreBoardSlot* widget = CreateWidget<UScoreBoardSlot>(GetWorld(), scoreBoardSlot);
			m_container->AddChild(widget);
			m_slots.Add(widget);
			widget->SetVisibility(ESlateVisibility::Hidden);
		}
	}
}

void UScoreBoard::UpdateScoreBoard(int32 sort)
{
	UWorld* world = GetWorld();
	if (!IsValid(world)) return;
	AGameStateBase* gameState = Cast<AGameStateBase>(world->GetGameState());
	if (!IsValid(gameState)) return;

	TArray<APlayerStateBase*> players = gameState->GetPlayers();

	// Fetch and update
	TArray<ADefaultPlayerState*> playersSorted;
	for (int32 i = 0; i < players.Num(); i++)
	{
		ADefaultPlayerState* const state = Cast<ADefaultPlayerState>(players[i]);
		if (!IsValid(state)) continue;
		state->UpdatePersona();
		playersSorted.Add(state);
	}

	// Sort based on category
	if(sort == 0)
		playersSorted.Sort([](const ADefaultPlayerState& i, const ADefaultPlayerState& j)->bool { return i.nickname < j.nickname; });
	else if(sort == 1)
		playersSorted.Sort([](const ADefaultPlayerState& i, const ADefaultPlayerState& j)->bool { return i.kills > j.kills; });
	else if (sort == 2)
		playersSorted.Sort([](const ADefaultPlayerState& i, const ADefaultPlayerState& j)->bool { return i.deaths > j.deaths; });
	else if (sort == 3)
		playersSorted.Sort([](const ADefaultPlayerState& i, const ADefaultPlayerState& j)->bool { return float(i.kills) / float(i.deaths) > float(j.kills) / float(j.deaths); });
	
	// Activate the slots and set them to the person
	for (int32 i = 0; i < m_slots.Num(); i++)
	{
		if (i >= playersSorted.Num())
		{
			m_slots[i]->SetVisibility(ESlateVisibility::Hidden);
			continue;
		}
		else
			m_slots[i]->SetVisibility(ESlateVisibility::Visible);

		ADefaultPlayerState* const state = playersSorted[i];

		m_slots[i]->SetVisibility(ESlateVisibility::Visible);
		m_slots[i]->Update(state->avatar, FText::FromString(state->nickname), state->kills, state->deaths, teamData->GetTeamColor(state->GetTeam()));
	}
}