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


#include "MoveDistanceFromClothingObjective.h"

#include "TimerManager.h"
#include "NakedDesire/Clothing/DroppedClothingSubsystem.h"
#include "NakedDesire/Player/NakedDesireCharacter.h"

#define LOCTEXT_NAMESPACE "Commissions.Objectives.MoveDistanceFromClothing"

namespace
{
	constexpr float PollIntervalSeconds = 0.2f;
}

void UMoveDistanceFromClothingObjective::OnActivate()
{
	if (Player)
		Player->GetWorldTimerManager().SetTimer(PollTimer, this, &UMoveDistanceFromClothingObjective::Poll, PollIntervalSeconds, true);
}

void UMoveDistanceFromClothingObjective::OnDeactivate()
{
	if (Player)
		Player->GetWorldTimerManager().ClearTimer(PollTimer);
	PollTimer.Invalidate();
}

void UMoveDistanceFromClothingObjective::Poll()
{
	NotifyConditionChanged();
}

bool UMoveDistanceFromClothingObjective::IsConditionMet() const
{
	const UDroppedClothingSubsystem* Dropped = GetDroppedClothing();
	if (!Dropped || !Player)
		return false;

	float Distance = 0.0f;
	if (!Dropped->GetDistanceToNearestDroppedClothing(Player->GetActorLocation(), Distance))
		return false; // nothing on the ground to move away from

	return Distance >= RequiredMeters * 100.0f;
}

float UMoveDistanceFromClothingObjective::GetProgress() const
{
	// While a hold timer is running (stay-away variant) defer to the base's elapsed-hold progress.
	if (bSatisfied || RequiredHoldSeconds > 0.0f)
		return Super::GetProgress();

	const UDroppedClothingSubsystem* Dropped = GetDroppedClothing();
	if (!Dropped || !Player)
		return 0.0f;

	float Distance = 0.0f;
	if (!Dropped->GetDistanceToNearestDroppedClothing(Player->GetActorLocation(), Distance))
		return 0.0f;

	const float TargetCm = RequiredMeters * 100.0f;
	return TargetCm > 0.0f ? FMath::Clamp(Distance / TargetCm, 0.0f, 1.0f) : 0.0f;
}

UDroppedClothingSubsystem* UMoveDistanceFromClothingObjective::GetDroppedClothing() const
{
	UWorld* World = Player ? Player->GetWorld() : nullptr;
	return World ? World->GetSubsystem<UDroppedClothingSubsystem>() : nullptr;
}

FText UMoveDistanceFromClothingObjective::GetDescription() const
{
	if (RequiredHoldSeconds > 0.0f)
	{
		return FText::Format(LOCTEXT("Timed", "Stay {0} m from your dropped clothes for {1} seconds"),
			FText::AsNumber(FMath::RoundToInt(RequiredMeters)), FText::AsNumber(FMath::RoundToInt(RequiredHoldSeconds)));
	}

	return FText::Format(LOCTEXT("Instant", "Get {0} m away from your dropped clothes"),
		FText::AsNumber(FMath::RoundToInt(RequiredMeters)));
}

#undef LOCTEXT_NAMESPACE