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


#include "StatsManager.h"
#include "Kismet/GameplayStatics.h"
#include "NakedDesire/Global/NakedDesireGameMode.h"

UStatsManager::UStatsManager()
{
	PrimaryComponentTick.bCanEverTick = true;
	PrimaryComponentTick.TickInterval = 1.0f;
}

void UStatsManager::BeginPlay()
{
	Super::BeginPlay();
	
	EmbarrassmentUpdate.Broadcast(Embarrassment, MaxEmbarrassment);
	StaminaUpdate.Broadcast(Stamina, MaxStamina);
	EnergyUpdate.Broadcast(Energy, MaxEnergy);
}

void UStatsManager::TickComponent(float DeltaTime, enum ELevelTick TickType,
	FActorComponentTickFunction* ThisTickFunction)
{
	DecreaseEnergy(0.9f);

	if (ObserverCount > 0)
	{
		// TODO (#05): replace 0.0f with ClothingManager->GetEffectiveCoverage() when that lands.
		constexpr float CoverageWeight = 0.0f;
		IncreaseEmbarrassment(EmbarrassmentGainRate * (1.0f - CoverageWeight) * DeltaTime);
	}
	else
	{
		DecreaseEmbarrassment(EmbarrassmentDecayRate * DeltaTime);
	}
}

void UStatsManager::SetObserved(const bool bObserved, const float CoverageWeight)
{
	ObserverCount = FMath::Max(0, bObserved ? ObserverCount + 1 : ObserverCount - 1);
}

void UStatsManager::IncreaseEmbarrassment(const float Amount)
{
	Embarrassment = FMath::Clamp(Embarrassment + Amount, 0, MaxEmbarrassment);
	EmbarrassmentUpdate.Broadcast(Embarrassment, MaxEmbarrassment);
	if (Embarrassment == MaxEmbarrassment)
	{
		ANakedDesireGameMode* GameMode = Cast<ANakedDesireGameMode>(UGameplayStatics::GetGameMode(this));
		GameMode->EndGameEmbarrassed();
	}
}

void UStatsManager::DecreaseEmbarrassment(const float Amount)
{
	Embarrassment = FMath::Clamp(Embarrassment - Amount, 0, MaxEmbarrassment);
	EmbarrassmentUpdate.Broadcast(Embarrassment, MaxEmbarrassment);
}

void UStatsManager::DecreaseStamina(const float Amount)
{
	Stamina = FMath::Clamp(Stamina - Amount, 0, MaxStamina);
	StaminaUpdate.Broadcast(Stamina, MaxStamina);
}

void UStatsManager::IncreaseStamina(const float Amount)
{
	Stamina = FMath::Clamp(Stamina + Amount, 0, MaxStamina);
	StaminaUpdate.Broadcast(Stamina, MaxStamina);
}

void UStatsManager::DecreaseEnergy(const float Amount)
{
	Energy = FMath::Clamp(Energy - Amount, 0, MaxEnergy);
	EnergyUpdate.Broadcast(Energy, MaxEnergy);
}

void UStatsManager::RestoreEnergy()
{
	Energy = MaxEnergy;
	EnergyUpdate.Broadcast(Energy, MaxEnergy);
}

