#include "ZMMOJobChangeNetworkHandler.h"

#include "Engine/GameInstance.h"
#include "Engine/World.h"
#include "ZeusNetworkSubsystem.h"

DEFINE_LOG_CATEGORY_STATIC(LogZMMOJobChange, Log, All);

bool UZMMOJobChangeNetworkHandler::ShouldCreateSubsystem(UObject* Outer) const
{
	// Mesmo criterio do AttributeNetworkHandler — so' em mundos de gameplay
	// (PIE / standalone in-game). Editor preview / front-end menu nao precisa.
	const UWorld* World = Cast<UWorld>(Outer);
	if (World == nullptr) { return false; }
	return World->WorldType == EWorldType::Game
		|| World->WorldType == EWorldType::PIE;
}

void UZMMOJobChangeNetworkHandler::Initialize(FSubsystemCollectionBase& Collection)
{
	Super::Initialize(Collection);

	if (UZeusNetworkSubsystem* Net = GetZeusNetSubsystem())
	{
		JobChangeResultHandle = Net->OnJobChangeResult.AddUObject(
			this, &UZMMOJobChangeNetworkHandler::HandleJobChangeResult);
		UE_LOG(LogZMMOJobChange, Log,
			TEXT("[ZMMOJobChangeNetworkHandler] Bind OnJobChangeResult OK"));
	}
	else
	{
		UE_LOG(LogZMMOJobChange, Warning,
			TEXT("[ZMMOJobChangeNetworkHandler] ZeusNetworkSubsystem indisponivel — bind pulado"));
	}
}

void UZMMOJobChangeNetworkHandler::Deinitialize()
{
	if (UZeusNetworkSubsystem* Net = GetZeusNetSubsystem())
	{
		if (JobChangeResultHandle.IsValid())
		{
			Net->OnJobChangeResult.Remove(JobChangeResultHandle);
			JobChangeResultHandle.Reset();
		}
	}
	OnJobChangeResult.Clear();
	Super::Deinitialize();
}

void UZMMOJobChangeNetworkHandler::HandleJobChangeResult(
	bool bAccepted, int32 Reason, int32 NewClassId)
{
	UE_LOG(LogZMMOJobChange, Log,
		TEXT("[ZMMOJobChangeNetworkHandler] S_JOB_CHANGE_RESULT accepted=%d reason=%d newClassId=%d"),
		bAccepted ? 1 : 0, Reason, NewClassId);
	OnJobChangeResult.Broadcast(bAccepted, Reason, NewClassId);
}

UZeusNetworkSubsystem* UZMMOJobChangeNetworkHandler::GetZeusNetSubsystem() const
{
	const UWorld* World = GetWorld();
	if (World == nullptr) { return nullptr; }
	UGameInstance* GI = World->GetGameInstance();
	if (GI == nullptr) { return nullptr; }
	return GI->GetSubsystem<UZeusNetworkSubsystem>();
}
