#pragma once

#include "CoreMinimal.h"
#include "CommonButtonBase.h"
#include "Layout/Margin.h"
#include "Types/SlateEnums.h"
#include "UI/UIStyleTypes.h"
#include "UI/UIStyleTokens.h"
#include "UIButton_Base.generated.h"

class UBorder;
class UTextBlock;
class UImage;
class USizeBox;
class UScaleBox;
class UCommonTextBlock;
class UCommonActionWidget;

DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnUIButtonActivatedByTimeout);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnUIButtonTimerUpdated, float, TimeRemaining);

/**
 * Botão base do ZMMO — porte 1:1 do UI_Button_Master do projeto Hyper para C++
 * auto-configurável, trocando o Struct_Style_Button do Hyper pela camada de
 * tema C++ (FUIStyle via UZMMOThemeSubsystem::GetActiveUIStyle()).
 *
 * Fundação: CommonUI (UCommonButtonBase) cuida de input/foco/click.
 * Camada Abstract (padrão "_Abstract" do Hyper). WBP UI_Button_Base herda
 * disto; UI_Button_Master herda do WBP. Os widgets visuais são opcionais
 * (BindWidgetOptional) e nomeados como no Hyper.
 *
 * Auto-config: NativePreConstruct chama InitializeButton (text/number/icon/
 * sizebox/estilo) + ApplyInputActionStyle. Reage à troca de tema.
 */
UCLASS(Abstract, Blueprintable)
class ZMMO_API UUIButton_Base : public UCommonButtonBase
{
	GENERATED_BODY()

public:
	// ---- Botão ----
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button")
	EUIButtonShape ButtonTypeSelection = EUIButtonShape::Rectangle;

	/**
	 * Variante visual do botão (dropdown vem de FUIStyle.Button.Backgrounds/
	 * Strokes/Fonts no DT_UI_Styles + as 4 clássicas como fallback).
	 * Data-driven via FName, sem enum fixo (padrão Hyper-style).
	 */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button",
		meta = (GetOptions = "GetVariantOptions"))
	FName Variant = TEXT("Primary");

	/** Opções do dropdown de Variant (data-driven do DT_UI_Styles). */
	UFUNCTION()
	TArray<FString> GetVariantOptions() const;

	/** Hyper "Transform Policy = To Upper": força o texto em maiúsculas. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button")
	bool bUppercaseText = true;

	// ---- Text Style ----
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Text Style")
	FText ButtonTextValue = FText::FromString(TEXT("Button Text"));

	/** Alinhamento do texto dentro do botão (esquerda/centro/direita). */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Text Style")
	TEnumAsByte<ETextJustify::Type> TextAlign = ETextJustify::Center;

	/** true = texto escala p/ caber no tamanho do botão (ScaleBox ScaleToFit);
	 *  false = usa o tamanho fixo da fonte da variante. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Text Style")
	bool bAutoSizeText = true;

	/** Arredonda o Background (RoundedBox) e desenha a borda na cor da
	 *  variante. Desligado = caixa reta. Raio/largura vêm de FUIStyleButton. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Button")
	bool bRoundedBackground = true;

	// ---- Number Text ----
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Number Text")
	bool bShowNumberText = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Number Text")
	int32 NumberTextAmount = 0;

	// ---- Icon ----
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Icon")
	bool bUseIconInsteadOfText = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Icon")
	TObjectPtr<UObject> IconImage = nullptr;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Icon")
	EUIIconType IconTypeSelection = EUIIconType::None;

	// ---- Size ----
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Size")
	float InHeightOverride = 50.f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Size")
	float InWidthOverride = 150.f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Size")
	bool bDoNotOverrideWithSizebox = false;

	// ---- Input Action Style ----
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input Action Style")
	bool bShowInputActionWidget = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input Action Style")
	FMargin InputPadding = FMargin(0.f, 0.f, 0.f, -22.f);

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input Action Style")
	TEnumAsByte<EHorizontalAlignment> InputHorzAlignment = HAlign_Center;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input Action Style")
	TEnumAsByte<EVerticalAlignment> InputVertAlignment = VAlign_Bottom;

	// ---- Deactivate by Timer ----
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Deactivate By Timer")
	bool bDeactivatedOnConstructWithTimeout = false;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Deactivate By Timer")
	float Timeout = 0.f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Timer")
	float TimeUpdateFrequency = 0.05f;

	UPROPERTY(BlueprintReadOnly, Category = "Timer")
	float TimeRemaining = 0.f;

	UPROPERTY(BlueprintAssignable, Category = "Timer")
	FOnUIButtonActivatedByTimeout OnButtonActivatedByTimeout;

	UPROPERTY(BlueprintAssignable, Category = "Timer")
	FOnUIButtonTimerUpdated OnButtonTimerUpdated;

	// ---- API (porte 1:1 das funções do Hyper) ----
	UFUNCTION(BlueprintCallable, Category = "UI Button")
	void SetButtonText(FText InText);

	UFUNCTION(BlueprintCallable, Category = "UI Button")
	void SetNumberText();

	UFUNCTION(BlueprintCallable, Category = "UI Button")
	void SetIcon();

	UFUNCTION(BlueprintCallable, Category = "UI Button")
	void ApplySizeBox();

	UFUNCTION(BlueprintCallable, Category = "UI Button")
	void ApplyInputActionStyle();

	/** Orquestrador (Hyper "Initialize Button"): aplica tudo + estilo do tema. */
	UFUNCTION(BlueprintCallable, Category = "UI Button")
	void InitializeButton();

	/** Re-resolve os tokens do tema ativo e reaplica (Hyper "Update Button Style"). */
	UFUNCTION(BlueprintCallable, Category = "UI Style")
	void RefreshUIStyle();

	/** Estado visual do botão (mapeia nos tokens BgNormal/Hover/Pressed/Disabled). */
	enum class EUIButtonVisual : uint8 { Normal, Hovered, Pressed, Disabled };

	/** Pinta o Background (fill + borda) conforme o estado, re-resolvendo o tema. */
	void ApplyVisualState(EUIButtonVisual State);

protected:
	virtual void NativePreConstruct() override;
	virtual void NativeConstruct() override;
	virtual void NativeDestruct() override;

	// Estados do UCommonButtonBase → repinta o Background pela variante.
	virtual void NativeOnHovered() override;
	virtual void NativeOnUnhovered() override;
	virtual void NativeOnPressed() override;
	virtual void NativeOnReleased() override;
	virtual void NativeOnEnabled() override;
	virtual void NativeOnDisabled() override;

	/** Hook opcional: o WBP pode estender/sobrescrever a aplicação visual. */
	UFUNCTION(BlueprintImplementableEvent, Category = "UI Style",
		meta = (DisplayName = "Apply UI Style"))
	void BP_ApplyUIStyle(const FUIStyleButton& Button, const FUIStyleButtonVariant& VariantStyle);

	FUIStyleButtonVariant ResolveVariant(const FUIStyleButton& Button) const;

	// ---- Widgets visuais opcionais (nomes espelham o Hyper) ----
	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<USizeBox> SizeBox_Master;

	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UCommonTextBlock> ButtonText;

	/** Envolve o ButtonText: escala o texto p/ caber no botão (bAutoSizeText). */
	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UScaleBox> TextScaleBox;

	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UTextBlock> Number_Text;

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

	/** Fundo temável (nossa adição sobre o Hyper, p/ FUIStyle). */
	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UBorder> Background;

private:
	void StartDeactivateTimeout();
	void HandleTimeoutFinished();
	void HandleTimerTick();

	UFUNCTION()
	void HandleThemeChanged(FName NewThemeId);

	bool bThemeBound = false;
	FTimerHandle InactivityTimer;
	FTimerHandle TimerTickHandle;
};
