#include "UISpinner_Base.h"

#include "ZMMOThemeSubsystem.h"
#include "Engine/GameInstance.h"
#include "Engine/DataTable.h"
#include "Components/CircularThrobber.h"
#include "UI/UIStyleRow.h"

namespace
{
	// Mesmo padrão de UUIPanel_Base: runtime usa o tema ativo; design-time
	// carrega a row "Default" de DT_UI_Styles para o Designer ver igual.
	const FUIStyle& ResolveSpinnerStyle(const UUserWidget* Widget, const FUIStyle& Fallback)
	{
		if (Widget)
		{
			if (const UGameInstance* GI = Widget->GetGameInstance())
			{
				if (const UZMMOThemeSubsystem* Theme = GI->GetSubsystem<UZMMOThemeSubsystem>())
				{
					return Theme->GetActiveUIStyle();
				}
			}
		}
		static FUIStyle DesignStyle;
		static bool bDesignLoaded = false;
		if (!bDesignLoaded)
		{
			if (const UDataTable* DT = LoadObject<UDataTable>(nullptr,
				TEXT("/Game/ZMMO/Data/UI/DT_UI_Styles.DT_UI_Styles")))
			{
				if (const FUIStyleRow* Row = DT->FindRow<FUIStyleRow>(
					FName(TEXT("Default")), TEXT("UISpinnerDesign"), false))
				{
					DesignStyle = Row->Style;
					bDesignLoaded = true;
				}
			}
		}
		return bDesignLoaded ? DesignStyle : Fallback;
	}
}

void UUISpinner_Base::RefreshUIStyle()
{
	const FUIStyle Fallback;
	const FUIStyle& AS = ResolveSpinnerStyle(this, Fallback);
	const FUIStyleSpinner& S = AS.Spinner;

	if (Throbber)
	{
		Throbber->SetNumberOfPieces(FMath::Max(1, S.NumberOfPieces));
		Throbber->SetPeriod(FMath::Max(0.05f, S.Period));
		Throbber->SetRadius(S.Radius);
	}

	// Cor/brush: o WBP aplica no throbber (mesma divisão de UUIPanel_Base).
	BP_ApplySpinnerStyle(S);
}

void UUISpinner_Base::NativePreConstruct()
{
	Super::NativePreConstruct();
	RefreshUIStyle();
}

void UUISpinner_Base::NativeConstruct()
{
	Super::NativeConstruct();

	if (!bThemeBound)
	{
		if (const UGameInstance* GI = GetGameInstance())
		{
			if (UZMMOThemeSubsystem* Theme = GI->GetSubsystem<UZMMOThemeSubsystem>())
			{
				Theme->OnThemeChanged.AddDynamic(this, &UUISpinner_Base::HandleThemeChanged);
				bThemeBound = true;
			}
		}
	}
	RefreshUIStyle();
}

void UUISpinner_Base::NativeDestruct()
{
	if (bThemeBound)
	{
		if (const UGameInstance* GI = GetGameInstance())
		{
			if (UZMMOThemeSubsystem* Theme = GI->GetSubsystem<UZMMOThemeSubsystem>())
			{
				Theme->OnThemeChanged.RemoveDynamic(this, &UUISpinner_Base::HandleThemeChanged);
			}
		}
		bThemeBound = false;
	}
	Super::NativeDestruct();
}

void UUISpinner_Base::HandleThemeChanged(FName /*NewThemeId*/)
{
	RefreshUIStyle();
}
