// Copyright Zeus Server Engine. All rights reserved.

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "ZeusAOIDebugTarget.h" // plugin ZeusAdminToolsRuntime: interface + EZeusAOIOverlay
#include "ZeusAOIComponent.generated.h"

/**
 *  UZeusAOIComponent (cliente / jogo)
 *
 *  Componente de gameplay do player local. Dominio principal: Area of Interest
 *  do cliente (proxies, despawn coordenado, interpolacao — ver
 *  [[project_aoi_client_component]]). AQUI, alem disso, expoe um "plus" de
 *  DEBUG: overlays via DrawDebug* dirigidos pelo painel admin (plugin) atraves
 *  de IZeusAOIDebugTarget, e/ou por console vars (zeus.debug.aoi etc.).
 *
 *  As DUAS zonas do AOI (Interesse interna + Despawn externa = histerese) vem do
 *  SERVIDOR: ao ligar um overlay (ou no BeginPlay) o componente pede a config via
 *  C_DEBUG_AOI_REQUEST e recebe S_DEBUG_AOI_INFO (delegate OnDebugAoiInfo do
 *  UZeusNetworkSubsystem) com interestRadiusCm + despawnRadiusCm. Enquanto nao
 *  chega (raio == 0), nao desenha (loading).
 *
 *  Vive na src do ZMMO (nao no plugin): e' um componente do JOGO. O plugin
 *  ZeusAdminTools apenas COMUNICA com ele via a interface — direcao da
 *  dependencia: ZMMO -> plugin (implementa a interface).
 */
UCLASS(ClassGroup = (Zeus), meta = (BlueprintSpawnableComponent), DisplayName = "Zeus AOI Component")
class ZMMO_API UZeusAOIComponent : public UActorComponent, public IZeusAOIDebugTarget
{
	GENERATED_BODY()

public:
	UZeusAOIComponent();

	virtual void BeginPlay() override;
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
	virtual void TickComponent(float DeltaTime, ELevelTick TickType,
	                           FActorComponentTickFunction* ThisTickFunction) override;

	// === IZeusAOIDebugTarget (dirigido pelo painel admin) ===
	virtual void SetOverlayEnabled_Implementation(EZeusAOIOverlay Overlay, bool bEnabled) override;
	virtual void SetAllOverlays_Implementation(bool bEnabled) override;
	virtual bool IsOverlayEnabled_Implementation(EZeusAOIOverlay Overlay) const override;
	virtual float GetInterestRadiusCm_Implementation() const override;
	virtual float GetDespawnRadiusCm_Implementation() const override;

	// === Flags de debug por overlay ===
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|AOI Debug|Overlays") bool bShowAOIRadius = false;    // Zona de Interesse
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|AOI Debug|Overlays") bool bShowDespawnZone = false;  // Zona de Despawn
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|AOI Debug|Overlays") bool bShowCellBounds = false;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|AOI Debug|Overlays") bool bShowProxyLabels = false;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|AOI Debug|Overlays") bool bShowHandoffLine = false;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|AOI Debug|Overlays") bool bShowAuthDrift = false;

	// === Parametros ===
	// Raios reais vem do servidor (S_DEBUG_AOI_INFO). 0 = ainda nao recebido (loading).
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Zeus|AOI Debug|Params") float InterestRadiusCm = 0.0f;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Zeus|AOI Debug|Params") float DespawnRadiusCm = 0.0f;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|AOI Debug|Params") float CellBoundsExtentCm = 50000.0f;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Zeus|AOI Debug|Params") float LineThickness = 2.0f;

	UFUNCTION(BlueprintPure, Category = "Zeus|AOI Debug")
	int32 GetEnabledOverlayCount() const;

private:
	void DrawOverlays();
	bool ResolveOverlay(EZeusAOIOverlay Overlay) const;
	bool AnyOverlayActive() const;

	/** Pede a config de AOI ao servidor (C_DEBUG_AOI_REQUEST). No-op se ja' temos
	 *  os raios ou se nao houver UZeusNetworkSubsystem conectado. */
	void RequestAoiConfig();

	/** Bind de UZeusNetworkSubsystem::OnDebugAoiInfo: armazena os raios reais. */
	void HandleAoiConfig(float InterestCm, float DespawnCm);

	/** Handle do bind do OnDebugAoiInfo (pra remover no EndPlay). */
	FDelegateHandle AoiConfigHandle_;
};
