// Project Lab - NHTV Igad

#pragma once

#include "GameFramework/Actor.h"
#include <unordered_set>
#include <map>
using std::unordered_set;
using std::map;
#include "SpawnerBase.generated.h"

UENUM(BlueprintType)
enum class NPCTeam : uint8
{
	Team1 = 50,
};

UCLASS()
class ASpawnerBase : public AActor
{
	GENERATED_BODY()

public:
	ASpawnerBase();

	virtual void BeginPlay() override;
	virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
	virtual void Tick(float DeltaTime) override;
	virtual void GetNewTarget(class ANPCBase* mob);
	UFUNCTION(BlueprintCallable, Category="Capture")
	virtual void CaptureCamp(int team);
	void ForceSetTarget(class ANPCBase* mob,class ANetworkPlayer* target);
	void ForceResetTarget(class ANPCBase* mob);
	void SetTeam(int team);
	class ANetworkPlayer* GetClosestPlayer();
	// Call when the camp is killed entirely
	UFUNCTION(NetMulticast, Reliable)
	void OnCampCleared();

	void AddThreat(class ANPCBase* creature, class ANetworkPlayer* character, int32 threat);

	virtual int32 OnMobDie(class ANPCBase* mob);

	virtual FVector SpawnResetPosition();

	int32 GetAliveMobCount();

	// m_nearbyPlayers but as ANetworkPlayer array instead of ANetworkCharacter's
	TArray<class ANetworkPlayer*> GetNearbyPlayers();

	UPROPERTY(EditAnywhere)
	float aggroRadius;
	UPROPERTY(EditAnywhere)
	float deaggroRadius;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FMod")
	float threatLevel;

	UPROPERTY(EditAnywhere, Replicated)
	NPCTeam team;

	UPROPERTY(EditAnywhere)
	FColor debugColorCode;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Display)
	class UStaticMeshComponent* displayMesh;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Display)
	class UArrowComponent* displayArrow;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Display)
	class UNetworkSwitchComponent* displayDoors;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Kill Particle")
	UParticleSystemComponent* killParticle;

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TArray<TSubclassOf<class ANPCBase>> spawns;
	UPROPERTY(EditAnywhere, Category = "Spawn Settings")
	float drawingRadius;
	UPROPERTY(EditAnywhere, Category = "Spawn Settings")
	float collisionScaler;
	UPROPERTY(EditAnywhere, Category = "Spawn Settings")
	float resetTimer;
	UPROPERTY(EditAnywhere, Category = "Spawn Settings")
	bool possesable;
	UPROPERTY(EditAnywhere, Category = "Spawn Settings")
	TArray<AActor*> SpawnLocation;

	bool isConnected;

	UPROPERTY(EditAnywhere, Category = "Switch Components")
	class UCreatureSpawnComponent* visualizerComponent;
	UPROPERTY(EditAnywhere, Category = "ControlPoints Settings")
	TArray<FVector2D> controlPoints;
	UPROPERTY(EditAnywhere, Category = "Formation Settings")
	float formationDistance;
	UPROPERTY(EditAnywhere, Category = "Formation Settings")
	float formationRadius;
	TArray<FVector2D> formationPoints;

	TArray<float> formationRotation;
	UPROPERTY(EditAnywhere, Category = "Formation Settings")
	float formationScale;
	TArray<class AEnemyBase*> formationEnemies;
	bool hasGeneral;

	UPROPERTY(EditAnywhere, Category = "Miniboss")
	int32 dropKeyFragmentIndex;
	bool hasDroppedKey;
	TArray<class ANPCBase*> m_mobs;
protected:
	virtual void m_OnCampCleared() {};
	virtual void m_OnPlayerEnterOverlap(class ANetworkCharacter& player);
	virtual	void m_OnPlayerExitOverlap(class ANetworkCharacter& player);
	class ANetworkPlayer* m_GetBiggestThreat(int32 index);
	


	void m_OnMobSpawn(int32 index);

	int32 m_mobCount;

	unordered_set<class ANetworkCharacter*> m_nearbyPlayers;
	TArray<map<class ANetworkPlayer*, int32>> m_threatMap;
	float m_resetTimer;
	//float formationDistance = 0;
	//float formationRadius = 0;
};