// Fill out your copyright notice in the Description page of Project Settings.


#include "StatusSystem.h"
#include <Runtime/Engine/Classes/Kismet/GameplayStatics.h>

#include "Blueprint/UserWidget.h"
#include "Components/Image.h"
#include "Components/TextBlock.h"

// Sets default values for this component's properties
UStatusSystem::UStatusSystem()
{
	// Set this component to be initialized when the game starts, and to be ticked every frame.  You can turn these features
	// off to improve performance if you don't need them.
	PrimaryComponentTick.bCanEverTick = true;
	static ConstructorHelpers::FClassFinder<UUserWidget> HUDStatusIndicatorsWidgetClassFinder(TEXT("/Game/Blueprints/Status_UI/StatusIndicator"));
	HUDStatusIndicatorsWidget = HUDStatusIndicatorsWidgetClassFinder.Class;
	static ConstructorHelpers::FClassFinder<UUserWidget> HUDStatusIconWidgetClassFinder(TEXT("/Game/Blueprints/Status_UI/StatusIcon"));
	HUDStatusIconWidget = HUDStatusIconWidgetClassFinder.Class;
}


// Called when the game starts
void UStatusSystem::BeginPlay()
{
	Super::BeginPlay();

	HUDStatusIndicators = CreateWidget<UUserWidget>(GetWorld(), HUDStatusIndicatorsWidget);
	HUDStatusIndicators->AddToViewport();
	StatusIconsBox = Cast<UWrapBox>(HUDStatusIndicators->GetWidgetFromName(TEXT("StatusIndicators")));
}


// Called every frame
void UStatusSystem::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
	Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
}

void UStatusSystem::AddStatusEffect(UStatusEffect* StatusEffect, const float DurationMultiplier, const bool Invoke)
{
	FActiveStatusEffect NewStatusEffect;
	NewStatusEffect.StatusEffect = StatusEffect;
	NewStatusEffect.TimeInitiated = UGameplayStatics::GetRealTimeSeconds(GetWorld());
	if (StatusEffect->IsForCombatOnly)
	{
		NewStatusEffect.TimeTillExpiry = StatusEffect->BaseDuration * DurationMultiplier;
	}
	else
	{
		NewStatusEffect.TimeTillExpiry = UGameplayStatics::GetRealTimeSeconds(GetWorld()) + StatusEffect->BaseDuration * DurationMultiplier;
	}
	NewStatusEffect.StatusIcon = CreateWidget<UUserWidget>(GetWorld(), HUDStatusIconWidget);
	UImage* StatusIconImage = Cast<UImage>(NewStatusEffect.StatusIcon->GetWidgetFromName(TEXT("StatusIconImage")));
	StatusIconImage->SetBrushFromTexture(StatusEffect->Icon);
	StatusIconsBox->AddChild(NewStatusEffect.StatusIcon);
	NewStatusEffect.StatusEffect->OnStatusEffectAdd(GetOwner());
	UTextBlock* StatusText = Cast<UTextBlock>(NewStatusEffect.StatusIcon->GetWidgetFromName(TEXT("DurationText")));
	StatusText->SetText(FText::FromString(FString::FromInt(NewStatusEffect.TimeTillExpiry)));
	if (Invoke) NewStatusEffect.StatusEffect->Invoke(GetOwner(), NewStatusEffect.TimeTillExpiry);

	ActiveStatusEffects.Add(NewStatusEffect);
}

void UStatusSystem::RemoveStatusEffect(UStatusEffect* StatusEffect)
{
	if (ActiveStatusEffects.Contains(FActiveStatusEffect{0, 0, StatusEffect, nullptr}))
	{
		ActiveStatusEffects.Remove(FActiveStatusEffect{0, 0, StatusEffect, nullptr});
	}
	else
	{
		UE_LOG(LogTemp, Warning, TEXT("StatusEffect not found in ActiveStatusEffects"));
	}
}

FActiveStatusEffect UStatusSystem::GetActiveStatusEffect(UStatusEffect* StatusEffect)
{
	if (ActiveStatusEffects.Contains(FActiveStatusEffect{0, 0, StatusEffect, nullptr}))
	{
		return ActiveStatusEffects[ActiveStatusEffects.Find(FActiveStatusEffect{0, 0, StatusEffect, nullptr})];
	}
	UE_LOG(LogTemp, Warning, TEXT("StatusEffect not found in ActiveStatusEffects"));
	return FActiveStatusEffect();
}