#pragma once

#include "CoreMinimal.h"
#include "Subsystems/WorldSubsystem.h"
#include "ZMMOJobChangeNetworkHandler.generated.h"

class UZeusNetworkSubsystem;

/**
 *  Multicast dinamico assignable em Blueprint. WBP de promocao binda no
 *  OnJobChangeResult pra reagir ao S_JOB_CHANGE_RESULT (1520) do server.
 *
 *  Parametros:
 *   - bAccepted    : true = promocao aplicada (S_ATTRIBUTE_SNAPSHOT_FULL
 *                    chega logo apos com state novo).
 *   - Reason       : EJobChangeRejectReason (None/NoSession/UnknownJob/
 *                    NotParent/WrongTier/JobLevelTooLow/AlreadyAtTarget/
 *                    JobsDbUnavailable). Significativo apenas se !bAccepted.
 *   - NewClassId   : significativo apenas se bAccepted=true (redundante com
 *                    snapshot que vem junto, mas util pra triggers/toasts).
 */
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FZMMOOnJobChangeResultBP,
	bool, bAccepted, int32, Reason, int32, NewClassId);

/**
 *  Bridge entre o `UZeusNetworkSubsystem` (do plugin ZeusNetwork) e a UI
 *  Blueprint (WBP de promocao). Mesmo pattern do `UZMMOAttributeNetworkHandler`
 *  — converte o delegate C++-only `FZeusOnJobChangeResult` num dynamic
 *  multicast (`FZMMOOnJobChangeResultBP`) assignavel em BP.
 *
 *  Por que UWorldSubsystem? Player so' faz promocao quando ja' esta no
 *  WorldServer (com mundo carregado). No front-end / lobby, esse subsystem
 *  nao existe — economiza memoria.
 */
UCLASS()
class ZMMOJOBS_API UZMMOJobChangeNetworkHandler : public UWorldSubsystem
{
	GENERATED_BODY()

public:
	virtual void Initialize(FSubsystemCollectionBase& Collection) override;
	virtual void Deinitialize() override;
	virtual bool ShouldCreateSubsystem(UObject* Outer) const override;

	/// Assignavel em BP: WBP_JobChangePanel.OnEvent_OnJobChangeResult.
	UPROPERTY(BlueprintAssignable, Category = "Zeus|Jobs")
	FZMMOOnJobChangeResultBP OnJobChangeResult;

private:
	void HandleJobChangeResult(bool bAccepted, int32 Reason, int32 NewClassId);
	UZeusNetworkSubsystem* GetZeusNetSubsystem() const;

	FDelegateHandle JobChangeResultHandle;
};
