// Copyright Pacificao. All Rights Reserved.

#include "AgrarianCampfire.h"
#include "AgrarianGameCharacter.h"
#include "AgrarianInventoryComponent.h"
#include "AgrarianSurvivalComponent.h"
#include "Components/PointLightComponent.h"
#include "Components/StaticMeshComponent.h"
#include "Kismet/GameplayStatics.h"
#include "Net/UnrealNetwork.h"

AAgrarianCampfire::AAgrarianCampfire()
{
	PrimaryActorTick.bCanEverTick = true;
	bReplicates = true;

	Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
	RootComponent = Mesh;

	FireLight = CreateDefaultSubobject<UPointLightComponent>(TEXT("FireLight"));
	FireLight->SetupAttachment(RootComponent);
	FireLight->SetIntensity(0.0f);
	FireLight->SetAttenuationRadius(WarmthRadius);
	FireLight->SetLightColor(FLinearColor(1.0f, 0.45f, 0.18f));
}

void AAgrarianCampfire::Tick(float DeltaSeconds)
{
	Super::Tick(DeltaSeconds);

	if (HasAuthority() && bLit)
	{
		FuelSeconds = FMath::Max(0.0f, FuelSeconds - DeltaSeconds);
		if (FuelSeconds <= 0.0f)
		{
			bLit = false;
			UpdateVisualState();
		}

		WarmNearbyCharacters(DeltaSeconds);
	}
}

void AAgrarianCampfire::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
	DOREPLIFETIME(AAgrarianCampfire, bLit);
	DOREPLIFETIME(AAgrarianCampfire, FuelSeconds);
}

FText AAgrarianCampfire::GetInteractionText_Implementation(const AAgrarianGameCharacter* Interactor) const
{
	return bLit ? FText::FromString(TEXT("Add fuel")) : FText::FromString(TEXT("Light fire"));
}

bool AAgrarianCampfire::CanInteract_Implementation(const AAgrarianGameCharacter* Interactor) const
{
	return Interactor != nullptr;
}

void AAgrarianCampfire::Interact_Implementation(AAgrarianGameCharacter* Interactor)
{
	if (!HasAuthority() || !Interactor)
	{
		return;
	}

	UAgrarianInventoryComponent* Inventory = Interactor->GetInventoryComponent();
	if (Inventory && Inventory->RemoveItem(TEXT("wood"), 1))
	{
		AddFuel(90.0f);
		bLit = true;
		UpdateVisualState();
	}
}

void AAgrarianCampfire::AddFuel(float Seconds)
{
	if (HasAuthority())
	{
		FuelSeconds += FMath::Max(0.0f, Seconds);
		if (FuelSeconds > 0.0f)
		{
			bLit = true;
		}
		UpdateVisualState();
	}
}

void AAgrarianCampfire::OnRep_FireState()
{
	UpdateVisualState();
}

void AAgrarianCampfire::UpdateVisualState()
{
	if (FireLight)
	{
		FireLight->SetIntensity(bLit ? 4200.0f : 0.0f);
	}
}

void AAgrarianCampfire::WarmNearbyCharacters(float DeltaSeconds)
{
	TArray<AActor*> Characters;
	UGameplayStatics::GetAllActorsOfClass(this, AAgrarianGameCharacter::StaticClass(), Characters);

	for (AActor* Actor : Characters)
	{
		AAgrarianGameCharacter* Character = Cast<AAgrarianGameCharacter>(Actor);
		if (!Character || FVector::DistSquared(Character->GetActorLocation(), GetActorLocation()) > FMath::Square(WarmthRadius))
		{
			continue;
		}

		if (UAgrarianSurvivalComponent* SurvivalComponent = Character->GetSurvivalComponent())
		{
			SurvivalComponent->AddWarmth(WarmthPerSecond * DeltaSeconds);
		}
	}
}
