#pragma once

#include "CommonActivatableWidget.h"
#include "CoreMinimal.h"
#include "ZMMOAttributeTypes.h"
#include "ZMMOStatusWindowWidget.generated.h"

class UButton;
class UTextBlock;
class UCommonButtonBase;
class UZMMOAttributeComponent;

/**
 *  Tela "Status" — atributos do jogador + alocacao via botões `+`.
 *
 *  Modo Menu: cursor visível, movimento bloqueado, Esc fecha. Push em
 *  UI.Layer.GameMenu pelo `UUIInGameFlowSubsystem::ToggleScreen(StatusWindow)`.
 *  HUD continua visível em UI.Layer.Game por baixo.
 *
 *  Composicao do WBP_StatusWindow (BindWidgetOptional pra permitir variantes):
 *   - Labels de stats primarios: StrText / AgiText / VitText / IntText / DexText / LukText
 *   - Botões +: PlusBtn_Str / PlusBtn_Agi / PlusBtn_Vit / PlusBtn_Int / PlusBtn_Dex / PlusBtn_Luk
 *   - Derivados (server-authoritative): AtkText / MatkText / DefText / MdefText /
 *     HitText / FleeText / CritText / AspdText
 *   - StatusPointText (pontos disponíveis pra alocar)
 *   - CloseBtn (fecha — fallback do Esc/back handler)
 *
 *  Workflow:
 *   1. NativeOnActivated: busca AttributeComponent (PlayerState do player local)
 *   2. Subscreve OnAttributesChanged + OnStatAllocReply
 *   3. Refresh inicial via snapshot atual
 *   4. Clique no `+X` chama `Comp->RequestStatAlloc(X, 1)` → server valida
 *   5. Server responde com S_ATTRIBUTE_STAT_ALLOC_OK + (se ok) snapshot novo
 *   6. UI atualiza via delegate
 */
UCLASS(Abstract, Blueprintable, BlueprintType)
class ZMMO_API UZMMOStatusWindowWidget : public UCommonActivatableWidget
{
	GENERATED_BODY()

public:
	UZMMOStatusWindowWidget(const FObjectInitializer& ObjectInitializer);

protected:
	virtual void NativeOnActivated() override;
	virtual void NativeOnDeactivated() override;

	/// Modo Menu: cursor visível + bloqueia input de gameplay (movimento).
	virtual TOptional<FUIInputConfig> GetDesiredInputConfig() const override;

	/// Texto dos stats (label + valor). BindWidgetOptional pra permitir
	/// WBPs custom (ex.: sem display de SP em variantes).
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* StrText = nullptr;
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* AgiText = nullptr;
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* VitText = nullptr;
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* IntText = nullptr;
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* DexText = nullptr;
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* LukText = nullptr;

	/// Pontos restantes pra alocar + label "Status Points: N".
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UTextBlock* StatusPointText = nullptr;

	/// Derivados (sempre calculados pelo servidor — cliente NUNCA recalcula).
	/// Mostra `base + bonus` quando aplicavel (camadas equip/buff vem do server
	/// pre-somadas no snapshot). BindWidgetOptional pra suportar HUDs minimalistas.
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* AtkText = nullptr;
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* MatkText = nullptr;
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* DefText = nullptr;
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* MdefText = nullptr;
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* HitText = nullptr;
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* FleeText = nullptr;
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* CritText = nullptr;
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status|Derived") UTextBlock* AspdText = nullptr;

	/// Botoes + por stat.
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* PlusBtn_Str = nullptr;
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* PlusBtn_Agi = nullptr;
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* PlusBtn_Vit = nullptr;
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* PlusBtn_Int = nullptr;
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* PlusBtn_Dex = nullptr;
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* PlusBtn_Luk = nullptr;

	/// Botao Close (fallback do Esc/back).
	UPROPERTY(BlueprintReadOnly, meta = (BindWidgetOptional), Category = "Zeus|Status") UButton* CloseBtn = nullptr;

private:
	void BindToLocalPlayer();
	void UnbindFromComponent();
	void RefreshFromSnapshot(const FZMMOAttributesSnapshot& Snap);

	UFUNCTION() void HandleAttributesChanged(const FZMMOAttributesSnapshot& Snapshot);
	UFUNCTION() void HandleStatAllocReply(bool bAccepted, int32 Reason);

	UFUNCTION() void OnPlusStr();
	UFUNCTION() void OnPlusAgi();
	UFUNCTION() void OnPlusVit();
	UFUNCTION() void OnPlusInt();
	UFUNCTION() void OnPlusDex();
	UFUNCTION() void OnPlusLuk();
	UFUNCTION() void OnCloseClicked();

	void RequestAlloc(int32 StatId);

	UPROPERTY(Transient)
	TWeakObjectPtr<UZMMOAttributeComponent> BoundComponent;
};
