// Copyright Epic Games, Inc. All Rights Reserved.

#include "CorruptedMemoryGameMode.h"

#include "CMGameInstance.h"
#include "CM_GameState.h"
#include "CM_PlayerState.h"
#include "CorruptedMemoryCharacter.h"
#include "GameFramework/GameStateBase.h"
#include "GameFramework/PlayerStart.h"
#include "GameFramework/PlayerState.h"
#include "Kismet/GameplayStatics.h"
#include "UObject/ConstructorHelpers.h"

ACorruptedMemoryGameMode::ACorruptedMemoryGameMode()
	: Super()
{
	// set default pawn class to our Blueprinted character
	static ConstructorHelpers::FClassFinder<APawn> PlayerPawnClassFinder(TEXT("/Game/FirstPerson/Blueprints/BP_FirstPersonCharacter"));
	DefaultPawnClass = PlayerPawnClassFinder.Class;

	static ConstructorHelpers::FClassFinder<ACharacter> PlayerCharacterClassFinder(TEXT("/Game/FirstPerson/Blueprints/BP_FirstPersonCharacter"));
	PlayerCharacterClass = PlayerCharacterClassFinder.Class;
}

void ACorruptedMemoryGameMode::PostLogin(APlayerController* NewPlayer)
{
	Super::PostLogin(NewPlayer);
	NewPlayer->GetPlayerState<ACM_PlayerState>()->ClientPlayerJoin();
}

void ACorruptedMemoryGameMode::BeginPlay()
{
	Super::BeginPlay();

	FString MapName = GetWorld()->GetMapName();
	MapName.RemoveFromStart(GetWorld()->StreamingLevelsPrefix);
	if (MapName == "ClientEntry") return;

	//Gets all PlayerStart Actors and sorts them by PlayerStartTag
	TArray<AActor*> PlayerStartActors;
	UGameplayStatics::GetAllActorsOfClass(GetWorld(), APlayerStart::StaticClass(), PlayerStartActors);
	PlayerStartActors.Sort([](const AActor& A, const AActor& B) { return FCString::Atoi(*Cast<APlayerStart>(&A)->PlayerStartTag.ToString()) < FCString::Atoi(*Cast<APlayerStart>(&B)->PlayerStartTag.ToString()); });
	for (const AActor* PlayerStartActor : PlayerStartActors)
	{
		SpawnPoints.Add(PlayerStartActor->GetActorTransform());
	}

	//Gets all store shelves in level
	TArray<AActor*> StoreShelves;
	UGameplayStatics::GetAllActorsWithTag(GetWorld(), "StoreShelf", StoreShelves);
	for (AActor* StoreShelf : StoreShelves)
	{
		Shelves.Add(Cast<ACM_Shelving>(StoreShelf));
	}
	Shelves[0]->GameplayTags.Add("Corrupted");
}

void ACorruptedMemoryGameMode::ServerSpawnPlayer_Implementation(APlayerController* PlayerController)
{
	if (!IsValid(PlayerController)) return;
	if (IsValid(PlayerController->GetPawn()))
	{
		PlayerController->GetPawn()->Destroy();
	}
	ACharacter* SpawnedPlayerCharacter = GetWorld()->SpawnActor<ACharacter>(PlayerCharacterClass, SpawnPoints[PlayerController->GetPlayerState<ACM_PlayerState>()->GetPlayerId()]);
	PlayerController->Possess(SpawnedPlayerCharacter);
}
