#pragma once

#include "CoreMinimal.h"
#include "CommonUserWidget.h"
#include "UI/UIStyleTokens.h"
#include "UI/UIStyleTypes.h"
#include "UILabel_Base.generated.h"

class UUIInput_Base;
class UCommonTextBlock;
class UVerticalBox;
class UHorizontalBox;

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FUILabelTextChanged, const FText&, Text);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FUILabelTextCommitted, const FText&, Text, ETextCommit::Type, CommitMethod);

/**
 * Composição "label + input" — dois arranjos pré-montados (Box_Stacked,
 * Row_Inline) onde cada Input_* é uma instância concreta de UI_Input_Master
 * (UUIInput_Base). Alterna VISIBILIDADE entre layouts (Stacked vs Inline);
 * nunca muta a árvore (mutar em construção/thumbnail crasha o editor).
 *
 * Encaminha a API de texto pro input ativo. Variant/HintText/FontSize/
 * PreferredWidth/bIsPassword são propagados pros DOIS filhos (preview
 * correto em qualquer LabelLayout).
 */
UCLASS(Abstract, Blueprintable)
class ZMMO_API UUILabel_Base : public UCommonUserWidget
{
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintCallable, Category = "UI Style")
	void RefreshUIStyle();

	UFUNCTION(BlueprintPure, Category = "Input")
	FText GetText() const;

	UFUNCTION(BlueprintCallable, Category = "Input")
	void SetText(FText InText);

	UFUNCTION(BlueprintCallable, Category = "Input")
	void SetHintTextRuntime(FText InHint);

	UFUNCTION(BlueprintCallable, Category = "Input")
	void SetIsPasswordRuntime(bool bInIsPassword);

	UPROPERTY(BlueprintAssignable, Category = "Input")
	FUILabelTextChanged OnTextChanged;

	UPROPERTY(BlueprintAssignable, Category = "Input")
	FUILabelTextCommitted OnTextCommitted;

	// ---- Rótulo ----
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Label")
	FText LabelText;

	/** Categoria tipográfica do rótulo (dropdown vem do DT_UI_Styles). */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Label",
		meta = (GetOptions = "GetLabelTextRoleOptions"))
	FName LabelTextRole = TEXT("Label");

	UFUNCTION()
	TArray<FString> GetLabelTextRoleOptions() const;

	/** Posição do rótulo (label acima x label à esquerda). */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Label")
	EUIInputLabelLayout LabelLayout = EUIInputLabelLayout::Stacked;

	// ---- Encaminhado pro input ----
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input",
		meta = (GetOptions = "GetVariantOptions"))
	FName Variant = TEXT("Box");

	UFUNCTION()
	TArray<FString> GetVariantOptions() const;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input")
	FText HintText;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input", meta = (ClampMin = "0"))
	float FontSize = 0.f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input|Size", meta = (ClampMin = "0"))
	float PreferredWidth = 0.f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input|Size", meta = (ClampMin = "0"))
	float PreferredHeight = 0.f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input")
	bool bIsPassword = false;

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

	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UVerticalBox> Box_Stacked;

	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UHorizontalBox> Row_Inline;

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

	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UUIInput_Base> Input_Stacked;

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

	UPROPERTY(meta = (BindWidgetOptional))
	TObjectPtr<UUIInput_Base> Input_Inline;

private:
	UUIInput_Base* ActiveInput() const;
	void ApplyLayout();
	void PropagateInputProps();
	void BindInputDelegates();
	void UnbindInputDelegates();

	UFUNCTION()
	void HandleChildTextChanged(const FText& Text);

	UFUNCTION()
	void HandleChildTextCommitted(const FText& Text, ETextCommit::Type CommitMethod);

	bool bInputBound = false;
};
