#pragma once

#include "CoreMinimal.h"
#include "Subsystems/WorldSubsystem.h"
#include "ZeusAttributesPayload.h"
#include "ZMMOAttributeNetworkHandler.generated.h"

class UZeusNetworkSubsystem;

/**
 *  Ponte entre o `UZeusNetworkSubsystem` (GameInstanceSubsystem do plugin
 *  ZeusNetwork) e os `UZMMOAttributeComponent` ligados aos atores do mundo.
 *
 *  Por que UWorldSubsystem (e nao GameInstanceSubsystem)?
 *   - O registry de atores (`UZMMOWorldSubsystem::GetActorByEntityId`) e'
 *     World-scoped, reset a cada OpenLevel.
 *   - World subsystem so existe enquanto ha mundo carregado, o que e' exato
 *     quando precisamos rotear snapshots (no front-end nao ha pawn).
 *
 *  Lifecycle: `Initialize` binda nos 3 delegates do ZeusNetworkSubsystem;
 *  `Deinitialize` unbinda. Conversao `FZeusAttributesPayload ->
 *  FZMMOAttributesSnapshot` (USTRUCT Blueprint) acontece aqui.
 */
UCLASS()
class ZMMOATTRIBUTES_API UZMMOAttributeNetworkHandler : public UWorldSubsystem
{
	GENERATED_BODY()

public:
	virtual void Initialize(FSubsystemCollectionBase& Collection) override;
	virtual void Deinitialize() override;

	virtual bool ShouldCreateSubsystem(UObject* Outer) const override;

private:
	void HandleAttributeSnapshotFull(const FZeusAttributesPayload& Payload);
	void HandleHpSpUpdate(int32 EntityId, int32 Hp, int32 Sp);
	void HandleLevelUp(int32 EntityId, int32 NewBaseLevel, int32 StatusPointDelta);
	void HandleStatAllocReply(bool bAccepted, int32 Reason);

	UZeusNetworkSubsystem* GetZeusNetSubsystem() const;

	/// Acha o AttributeComponent do player local (Pawn->PlayerState).
	/// Usado pro StatAllocReply (sem EntityId no payload).
	class UZMMOAttributeComponent* FindLocalPlayerAttributeComponent() const;

	FDelegateHandle SnapshotFullHandle;
	FDelegateHandle HpSpUpdateHandle;
	FDelegateHandle LevelUpHandle;
	FDelegateHandle StatAllocReplyHandle;
};
