#include "ZeusHudPlayerVitalsWidget.h"

#include "Components/RichTextBlock.h"
#include "Components/TextBlock.h"
#include "UI/Widgets/UIProgressBar_Base.h"
#include "Internationalization/Text.h"

namespace
{
	float SafeRatio(int32 Current, int32 Max)
	{
		return Max > 0 ? FMath::Clamp(static_cast<float>(Current) / static_cast<float>(Max), 0.f, 1.f) : 0.f;
	}

	/** Ratio 0..1 pras barras de EXP/JOB (int64). ToNext<=0 = cap -> barra cheia. */
	float ExpRatio(int64 Cur, int64 ToNext)
	{
		return ToNext > 0
			? FMath::Clamp(static_cast<float>(static_cast<double>(Cur) / static_cast<double>(ToNext)), 0.f, 1.f)
			: 1.f;
	}

	/** Readout de progressao em "%": numero (Default) + "%" (unit/cinza).
	 *  Cap (ToNext<=0) -> "MAX". Markup resolve no DT_UI_VitalsReadout. */
	FText ExpReadoutText(int64 Cur, int64 ToNext)
	{
		if (ToNext <= 0) { return FText::FromString(TEXT("MAX")); }
		const double Pct = static_cast<double>(Cur) / static_cast<double>(ToNext) * 100.0;
		return FText::FromString(FString::Printf(TEXT("%.2f<unit>%%</>"), Pct));
	}
}

void UZeusHudPlayerVitalsWidget::ApplySnapshot(const FZeusAttributesSnapshot& Snapshot)
{
	LastSnapshot = Snapshot;

	// HP / SP (pool efetivo — % real)
	ApplyHpSp(Snapshot.Hp, Snapshot.MaxHp, Snapshot.Sp, Snapshot.MaxSp);

	// Level — markup: "LVL " (pct/cinza) + número (num/gold-bright maior)
	if (LvlText)
	{
		LvlText->SetText(FText::FromString(
			FString::Printf(TEXT("<pct>LVL </><num>%d</>"), Snapshot.BaseLevel)));
	}

	// BASE / JOB EXP — barras em % (exp atual / exp-to-next, resolvido pelo
	// server via JobsDatabase). Em cap (ToNext=0) a barra enche e o readout
	// vira "MAX". Readout exibe a porcentagem (numero + "%" cinza).
	if (ExpBar)
	{
		ExpBar->SetTargetPrimaryLevel(ExpRatio(Snapshot.BaseExp, Snapshot.BaseExpToNext));
	}
	if (JobBar)
	{
		JobBar->SetTargetPrimaryLevel(ExpRatio(Snapshot.JobExp, Snapshot.JobExpToNext));
	}
	if (ExpReadout)
	{
		ExpReadout->SetText(ExpReadoutText(Snapshot.BaseExp, Snapshot.BaseExpToNext));
	}
	if (JobReadout)
	{
		JobReadout->SetText(ExpReadoutText(Snapshot.JobExp, Snapshot.JobExpToNext));
	}

	OnSnapshotApplied(Snapshot);
}

void UZeusHudPlayerVitalsWidget::ApplyHpSp(int32 Hp, int32 MaxHp, int32 Sp, int32 MaxSp)
{
	LastSnapshot.Hp = Hp;
	LastSnapshot.MaxHp = MaxHp;
	LastSnapshot.Sp = Sp;
	LastSnapshot.MaxSp = MaxSp;

	if (HpBar)
	{
		HpBar->SetTargetPrimaryLevel(SafeRatio(Hp, MaxHp));
	}
	if (SpBar)
	{
		SpBar->SetTargetPrimaryLevel(SafeRatio(Sp, MaxSp));
	}
	// Markup RichText: atual (Default/branco) + "/" (sep/escuro) + max (max/cinza).
	// Tags resolvem no DT_UI_VitalsReadout (TextStyleSet do RichTextBlock).
	auto MakeReadout = [](int32 Cur, int32 Max) -> FText
	{
		return FText::FromString(FString::Printf(TEXT("%s<sep>/</><max>%s</>"),
			*FText::AsNumber(Cur).ToString(), *FText::AsNumber(Max).ToString()));
	};
	if (HpReadout)
	{
		HpReadout->SetText(MakeReadout(Hp, MaxHp));
	}
	if (SpReadout)
	{
		SpReadout->SetText(MakeReadout(Sp, MaxSp));
	}
}

void UZeusHudPlayerVitalsWidget::SetCharName(const FString& InName)
{
	if (NameText)
	{
		NameText->SetText(FText::FromString(InName));
	}
}

void UZeusHudPlayerVitalsWidget::SetClassName(const FString& InClassName)
{
	if (ClassText)
	{
		ClassText->SetText(FText::FromString(InClassName));
	}
}

void UZeusHudPlayerVitalsWidget::OnSnapshotApplied_Implementation(const FZeusAttributesSnapshot& /*Snapshot*/)
{
	// Default vazio — skin do WBP estende se quiser (low-HP flash, etc.).
}
