// © 2025 Naked People Team. All Rights Reserved.


#include "NPCSpawner.h"
#include "NPC.h"
#include "Kismet/GameplayStatics.h"
#include "NakedDesire/Global/NakedDesireGameMode.h"

ANPCSpawner::ANPCSpawner()
{
	PrimaryActorTick.bCanEverTick = false;
}

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

	PlayerCharacter = UGameplayStatics::GetPlayerCharacter(GetWorld(), 0);

	FTimerHandle TimerHandle;
	const int32 RandomDelay = FMath::RandRange(5, 30);
	GetWorldTimerManager().SetTimer(TimerHandle, this, &ANPCSpawner::OnTimerTick, 30, true, RandomDelay);
	OnTimerTick();

	if (AGameModeBase* CurrentGameMode = UGameplayStatics::GetGameMode(GetWorld()))
	{
		GameMode = Cast<ANakedDesireGameMode>(CurrentGameMode);
	}
}

void ANPCSpawner::OnTimerTick()
{
	if (!PlayerCharacter || !GameMode)
	{
		return;
	}
	
	const bool IsPlayerClose = FVector::Dist(PlayerCharacter->GetActorLocation(), GetActorLocation()) < 5000;
	const FTimecode CurrentTime = GameMode->GetCurrentTime();
	const bool IsDay = CurrentTime.Hours >= 9.0f && CurrentTime.Hours < 21.00f;
	const bool CanSpawnMore = IsDay ? NPCs.Num() < MaxCountDay : NPCs.Num() < MaxCountNight;
	
	if (CanSpawnMore && PlayerCharacter && IsPlayerClose && (FMath::RandBool() && !AlwaysSpawn))
	{
		FActorSpawnParameters SpawnParameters;
		SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
		const int RandomIndex = FMath::RandRange(0, NPCClasses.Num() - 1);
		ANPC* NewNPC = GetWorld()->SpawnActor<ANPC>(NPCClasses[RandomIndex], GetActorLocation(), GetActorRotation(), SpawnParameters);
		NewNPC->OnDestroyed.AddUObject(this, &ANPCSpawner::OnNPCDestroyed);
		NPCs.Add(NewNPC);
	}
}

void ANPCSpawner::OnNPCDestroyed(ANPC* NPC)
{
	NPCs.Remove(NPC);
}

