#pragma once

#include "CoreMinimal.h"
#include "CommonUserWidget.h"
#include "UI/UIStyleTypes.h"
#include "UIProgressBar_Base.generated.h"

class UImage;
class UMaterialInstanceDynamic;
struct FUIStyleProgressBarVariant;

/**
 *  ProgressBar do ZMMO. Wrappa um UImage (FillImage) + UImage de background
 *  (BackgroundImage) com material custom. O arredondamento dos cantos usa
 *  o RoundedBox nativo do Slate (Brush.DrawAs + OutlineSettings.CornerRadii)
 *  pra ficar pixel-perfect e independente do aspect ratio.
 *
 *  Modelo assimetrico de niveis: SecondaryLevel so aparece visualmente se
 *  for MAIOR que PrimaryLevel — representa heal preview, damage trail,
 *  buffer empilhado em cima da barra principal.
 */
UCLASS(Abstract, Blueprintable)
class ZMMO_API UUIProgressBar_Base : public UCommonUserWidget
{
	GENERATED_BODY()

public:
	// === Theme (DT_UI_Styles integration) ===

	/**
	 * true  = le toda a config visual (materiais + style + toggles) do
	 *         DT_UI_Styles (FUIStyleProgressBar.Variants[Variant]). Tema
	 *         centralizado, ignora as UPROPERTYs override individuais abaixo.
	 * false = ignora a DT, usa apenas as UPROPERTYs/toggles do widget.
	 */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Theme")
	bool bUseTheme = false;

	/**
	 * Chave da variante (HP/MP/XP/Cast/...). Dropdown popula via
	 * meta=GetOptions lendo DT_UI_Styles.Default.ProgressBar.Variants. Vazio
	 * = sem theme aplicado (igual bUseTheme=false).
	 */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Theme",
		meta = (EditCondition = "bUseTheme", EditConditionHides,
		        GetOptions = "GetProgressBarVariantOptions"))
	FName Variant;

	/** Re-resolve a variante atual e reaplica nos widgets. */
	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Theme")
	void RefreshUIStyle();

	/** Populador do dropdown (meta=GetOptions) das variantes. */
	UFUNCTION()
	TArray<FString> GetProgressBarVariantOptions() const;

	// === Levels ===

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar",
		meta = (ClampMin = "0", ClampMax = "1"))
	float InitialPrimaryLevel = 1.f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar",
		meta = (ClampMin = "0", ClampMax = "1"))
	float InitialSecondaryLevel = 0.f;

	// === Animation ===

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Animation",
		meta = (ClampMin = "0", ClampMax = "5"))
	float PrimaryAnimationSeconds = 0.25f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Animation",
		meta = (ClampMin = "0", ClampMax = "5"))
	float SecondaryAnimationSeconds = 0.8f;

	// === Draw Style ===

	/** Box=DrawAs Image (sem corner), Rounded=DrawAs RoundedBox (cantos arredondados). */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Style")
	EUIProgressBarStyle DrawStyle = EUIProgressBarStyle::Box;

	/**
	 * Raio dos cantos em PIXELS. Aplicado quando DrawStyle = Rounded.
	 * Se RoundingType = HalfHeightRadius (default do Slate), o Slate clampeia
	 * automaticamente em metade da altura — ou seja, valor maior que isso vira pill.
	 */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Style",
		meta = (ClampMin = "0", ClampMax = "100"))
	float CornerRadius = 8.f;

	/** Cor do outline em volta do Background (Slate OutlineSettings.Color). */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Style",
		meta = (InlineEditConditionToggle))
	bool bShowBorder = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Style",
		meta = (EditCondition = "bShowBorder"))
	FLinearColor BorderColour = FLinearColor(0.f, 0.f, 0.f, 0.8f);

	/** Espessura do outline em pixels. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Style",
		meta = (EditCondition = "bShowBorder", ClampMin = "0", ClampMax = "10"))
	float BorderWidth = 1.f;

	// === Color overrides (Fill material) ===

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Colors",
		meta = (InlineEditConditionToggle))
	bool bOverridePrimaryColour = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Colors",
		meta = (EditCondition = "bOverridePrimaryColour"))
	FLinearColor PrimaryColour = FLinearColor(0.957f, 0.769f, 0.353f, 1.f);

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Colors",
		meta = (InlineEditConditionToggle))
	bool bOverridePrimaryColourBottom = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Colors",
		meta = (EditCondition = "bOverridePrimaryColourBottom"))
	FLinearColor PrimaryColourBottom = FLinearColor(0.478f, 0.282f, 0.094f, 1.f);

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Colors",
		meta = (InlineEditConditionToggle))
	bool bOverrideSecondaryColour = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Colors",
		meta = (EditCondition = "bOverrideSecondaryColour"))
	FLinearColor SecondaryColour = FLinearColor(0.246201f, 0.002428f, 0.002125f, 1.f);

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Colors",
		meta = (InlineEditConditionToggle))
	bool bOverrideSecondaryColourBottom = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Colors",
		meta = (EditCondition = "bOverrideSecondaryColourBottom"))
	FLinearColor SecondaryColourBottom = FLinearColor(0.123f, 0.001f, 0.001f, 1.f);

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Colors",
		meta = (InlineEditConditionToggle))
	bool bOverrideEmptyColour = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Colors",
		meta = (EditCondition = "bOverrideEmptyColour"))
	FLinearColor EmptyColour = FLinearColor(0.f, 0.f, 0.f, 0.6f);

	// === Background override ===

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Background",
		meta = (InlineEditConditionToggle))
	bool bOverrideBackgroundColour = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Background",
		meta = (EditCondition = "bOverrideBackgroundColour"))
	FLinearColor BackgroundColour = FLinearColor(0.f, 0.f, 0.f, 0.6f);

	// === Track Grid (efeito de listras verticais sobre o BG) ===

	/** Liga/desliga a renderização do TrackGridImage. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|TrackGrid")
	bool bShowTrackGrid = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|TrackGrid",
		meta = (InlineEditConditionToggle))
	bool bOverrideGridColour = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|TrackGrid",
		meta = (EditCondition = "bOverrideGridColour"))
	FLinearColor GridColour = FLinearColor(1.f, 1.f, 1.f, 0.05f);

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|TrackGrid",
		meta = (InlineEditConditionToggle))
	bool bOverrideGridDivisions = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|TrackGrid",
		meta = (EditCondition = "bOverrideGridDivisions", ClampMin = "2", ClampMax = "50"))
	float GridDivisions = 10.f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|TrackGrid",
		meta = (InlineEditConditionToggle))
	bool bOverrideGridLineThickness = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|TrackGrid",
		meta = (EditCondition = "bOverrideGridLineThickness", ClampMin = "0.001", ClampMax = "0.2"))
	float GridLineThickness = 0.02f;

	// === Edge (linha vertical no fim do Primary) ===

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Edge")
	bool bShowEdge = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Edge",
		meta = (InlineEditConditionToggle))
	bool bOverrideEdgeColour = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Edge",
		meta = (EditCondition = "bOverrideEdgeColour"))
	FLinearColor EdgeColour = FLinearColor(1.f, 0.94f, 0.78f, 0.85f);

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Edge",
		meta = (InlineEditConditionToggle))
	bool bOverrideEdgeWidth = false;

	/** Largura da linha em UV (fração da barra). 0.005 ≈ 2px em barra de 400px. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Edge",
		meta = (EditCondition = "bOverrideEdgeWidth", ClampMin = "0.001", ClampMax = "0.1"))
	float EdgeWidth = 0.005f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Edge",
		meta = (InlineEditConditionToggle))
	bool bOverrideEdgeGlowWidth = false;

	/** Largura do halo lateral em UV. 0 = sem glow. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Edge",
		meta = (EditCondition = "bOverrideEdgeGlowWidth", ClampMin = "0", ClampMax = "0.2"))
	float EdgeGlowWidth = 0.02f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Edge",
		meta = (InlineEditConditionToggle))
	bool bOverrideEdgeGlowIntensity = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Edge",
		meta = (EditCondition = "bOverrideEdgeGlowIntensity", ClampMin = "0", ClampMax = "1"))
	float EdgeGlowIntensity = 0.5f;

	// === Shimmer (faixa de luz animada por cima do Fill) ===

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Shimmer")
	bool bShowShimmer = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Shimmer",
		meta = (InlineEditConditionToggle))
	bool bOverrideShimmerColour = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Shimmer",
		meta = (EditCondition = "bOverrideShimmerColour"))
	FLinearColor ShimmerColour = FLinearColor(1.f, 0.94f, 0.78f, 0.35f);

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Shimmer",
		meta = (InlineEditConditionToggle))
	bool bOverrideShimmerWidth = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Shimmer",
		meta = (EditCondition = "bOverrideShimmerWidth", ClampMin = "0.05", ClampMax = "1.0"))
	float ShimmerWidth = 0.2f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Shimmer",
		meta = (InlineEditConditionToggle))
	bool bOverrideShimmerSpeed = false;

	/** Ciclos por segundo. 0.4545 = ciclo de 2.2s (default CSS). */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Shimmer",
		meta = (EditCondition = "bOverrideShimmerSpeed", ClampMin = "0.01", ClampMax = "5.0"))
	float ShimmerSpeed = 0.4545f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Shimmer",
		meta = (InlineEditConditionToggle))
	bool bOverrideShimmerSoftness = false;

	/** Expoente da bell curve. Maior = pico mais fino. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Shimmer",
		meta = (EditCondition = "bOverrideShimmerSoftness", ClampMin = "0.5", ClampMax = "8.0"))
	float ShimmerSoftness = 2.f;

	// === Gradient overrides ===

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Gradient",
		meta = (InlineEditConditionToggle))
	bool bOverrideEnableGradient = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Gradient",
		meta = (EditCondition = "bOverrideEnableGradient"))
	bool bEnableGradient = true;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Gradient",
		meta = (InlineEditConditionToggle))
	bool bOverrideGradientSplit = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ProgressBar|Gradient",
		meta = (EditCondition = "bOverrideGradientSplit", ClampMin = "0", ClampMax = "1"))
	float GradientSplit = 0.5f;

	// === Primary API ===

	UFUNCTION(BlueprintCallable, Category = "ProgressBar")
	void SetTargetPrimaryLevel(float Primary01);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar")
	void SetPrimaryLevelImmediate(float Primary01);

	UFUNCTION(BlueprintPure, Category = "ProgressBar")
	float GetCurrentPrimaryLevel() const { return CurrentPrimaryLevel; }

	// === Secondary API ===

	UFUNCTION(BlueprintCallable, Category = "ProgressBar")
	void SetTargetSecondaryLevel(float Sec01);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar")
	void SetSecondaryLevelImmediate(float Sec01);

	UFUNCTION(BlueprintPure, Category = "ProgressBar")
	float GetCurrentSecondaryLevel() const { return CurrentSecondaryLevel; }

	// === Style API ===

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Style")
	void SetDrawStyle(EUIProgressBarStyle InStyle);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Style")
	void SetCornerRadius(float RadiusPixels);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Style")
	void SetBorderVisible(bool bVisible);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Style")
	void SetBorderColour(FLinearColor Color);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Style")
	void SetBorderWidth(float WidthPixels);

	// === Color setters (Fill MID) ===

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Colors")
	void SetPrimaryColour(FLinearColor Color);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Colors")
	void SetPrimaryColourBottom(FLinearColor Color);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Colors")
	void SetSecondaryColour(FLinearColor Color);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Colors")
	void SetSecondaryColourBottom(FLinearColor Color);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Colors")
	void SetEmptyColour(FLinearColor Color);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Background")
	void SetBackgroundColour(FLinearColor Color);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|TrackGrid")
	void SetTrackGridVisible(bool bVisible);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|TrackGrid")
	void SetGridColour(FLinearColor Color);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|TrackGrid")
	void SetGridDivisions(float Divisions);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|TrackGrid")
	void SetGridLineThickness(float Thickness);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Edge")
	void SetEdgeVisible(bool bVisible);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Edge")
	void SetEdgeColour(FLinearColor Color);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Edge")
	void SetEdgeWidth(float Width01);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Edge")
	void SetEdgeGlowWidth(float GlowWidth01);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Edge")
	void SetEdgeGlowIntensity(float Intensity01);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Shimmer")
	void SetShimmerVisible(bool bVisible);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Shimmer")
	void SetShimmerColour(FLinearColor Color);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Shimmer")
	void SetShimmerWidth(float Width01);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Shimmer")
	void SetShimmerSpeed(float Speed);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Shimmer")
	void SetShimmerSoftness(float Softness);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Gradient")
	void SetGradientEnabled(bool bEnabled);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Gradient")
	void SetGradientSplit(float Split01);

	// === Wrappers semânticos ===

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Effects")
	void ShowHealPreview(float TargetPct, FLinearColor PreviewColor);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Effects")
	void ShowDamageLag(float OldPct, float NewPct, FLinearColor LagColor);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Effects")
	void ShowBuffer(float BufferPct, FLinearColor BufferColor);

	UFUNCTION(BlueprintCallable, Category = "ProgressBar|Effects")
	void ClearSecondary();

protected:
	virtual void NativePreConstruct() override;
	virtual void NativeConstruct() override;
	virtual void NativeDestruct() override;
	virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime) override;

	UPROPERTY(meta = (BindWidget))
	TObjectPtr<UImage> FillImage;

	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UImage> BackgroundImage;

	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UImage> TrackGridImage;

	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UImage> EdgeImage;

	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UImage> ShimmerImage;

private:
	UPROPERTY(Transient)
	TObjectPtr<UMaterialInstanceDynamic> FillMID;

	UPROPERTY(Transient)
	TObjectPtr<UMaterialInstanceDynamic> BackgroundMID;

	UPROPERTY(Transient)
	TObjectPtr<UMaterialInstanceDynamic> TrackGridMID;

	UPROPERTY(Transient)
	TObjectPtr<UMaterialInstanceDynamic> EdgeMID;

	UPROPERTY(Transient)
	TObjectPtr<UMaterialInstanceDynamic> ShimmerMID;

	void EnsureMIDs();
	void ApplyPrimaryToMID(float Value);
	void ApplySecondaryToMID(float Value);
	void ApplyMaterialOverrides();
	void ApplyBrushStyle();
	void UpdateEdgeVisibility();
	void ApplyThemeVariant(const FUIStyleProgressBarVariant& Variant);

	UFUNCTION()
	void HandleThemeChanged(FName NewThemeId);

	bool bThemeBound = false;

	float CurrentPrimaryLevel = 1.f;
	float TargetPrimaryLevel = 1.f;
	float PrimaryStart = 1.f;
	float PrimaryElapsed = 0.f;
	bool bAnimatingPrimary = false;

	float CurrentSecondaryLevel = 0.f;
	float TargetSecondaryLevel = 0.f;
	float SecondaryStart = 0.f;
	float SecondaryElapsed = 0.f;
	bool bAnimatingSecondary = false;
};
