// Project Lab - NHTV Igad

#include "UnrealProject.h"
#include "RangedEnemy.h"
#include "AbilityInfo.h"
#include "SpawnerBase.h"
#include "NetworkPlayer.h"
#include "MinionAnimInstance.h"

ARangedEnemy::ARangedEnemy()
{
	PrimaryActorTick.bCanEverTick = true;
}
void ARangedEnemy::BeginPlay()
{
	Super::BeginPlay();
	if (Role != ROLE_Authority)
		return;
}
void ARangedEnemy::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
	Super::EndPlay(EndPlayReason);
	if (Role != ROLE_Authority)
		return;
}
void ARangedEnemy::Tick(float deltaTime)
{
	Super::Tick(deltaTime);
	if (Role != ROLE_Authority)
		return;
	if (IsValid(target))
	{
		
		if (!hasGeneral)
		{
			if (m_confusionTimer > 0.0f)
			{
				ConfusionBehavior();
				return;
			}
			BasicBehavior();
		}
		else
		{
			GeneralBehavior();
		}
		// Move to target

	}

}
void ARangedEnemy::BasicBehavior()
{
	if (!IsValid(target))
		return;
	const FVector2D actorLocation = FVector2D(GetActorLocation().X, GetActorLocation().Y);
	const FVector2D targetLocation = FVector2D(target->GetActorLocation().X, target->GetActorLocation().Y);
	const FVector2D spawnLocation = FVector2D(m_spawn->GetActorLocation());
	const float targetDistSqr = FVector2D::DistSquared(targetLocation, actorLocation);
	const float spawnTargetDistSqr = FVector2D::DistSquared(targetLocation, spawnLocation);

	if (!meleeAbility || !specialAbility)
	{
		RERROR("there is no abilities");
		return;
	}
	if (!rangedAbility)
	{
		RERROR("Ranged enemy does not have a ranged ability");
	}
	float 	castRange = rangedAbility->AICastRange;
	// walking code
	float testPercentage = (spawnTargetDistSqr) / ((m_spawn->aggroRadius + castRange)*(m_spawn->aggroRadius + castRange));

	FVector newLocation = (target->GetActorLocation() - m_spawn->GetActorLocation());
	newLocation.Normalize();
	newLocation *= m_spawn->aggroRadius*testPercentage;
	FVector walkLocation = newLocation + m_spawn->GetActorLocation();
	if (m_lastPercentage < testPercentage)
		MoveToPoint(walkLocation);
	m_lastPercentage = testPercentage;

	m_tempAbility = rangedAbility;
	if (targetDistSqr < (200 * 200))
	{
		m_tempAbility = meleeAbility;
		if ((rand() % 1000) > specialAbilityChance)
		{
			m_tempAbility = specialAbility;
		}
	}
	if (((m_tempAbility->AICastRange + 100)*(m_tempAbility->AICastRange + 100)) < targetDistSqr)
		return;
	if (GetAbilityState(m_tempAbility)->onCooldownTimer <= 0)
	{
		ChangeNPCAnimation((uint8)EMinionAnimState::MAS_Casting);
		CastAbility(m_tempAbility);
	}
	SetActorRotation(FVector(target->GetActorLocation() - GetActorLocation()).Rotation());
}
void ARangedEnemy::GeneralBehavior()
{
	const FVector2D actorLocation = FVector2D(GetActorLocation().X, GetActorLocation().Y);
	const FVector2D targetLocation = FVector2D(target->GetActorLocation().X, target->GetActorLocation().Y);
	const FVector2D spawnLocation = FVector2D(m_spawn->GetActorLocation());
	const float targetDistSqr = FVector2D::DistSquared(targetLocation, actorLocation);
	const float spawnTargetDistSqr = FVector2D::DistSquared(targetLocation, spawnLocation);

	if (!meleeAbility || !specialAbility)
	{
		RERROR("there is no abilities");
		return;
	}
	if (!rangedAbility)
	{
		RERROR("Ranged enemy does not have a ranged ability");
	}
	float 	castRange = rangedAbility->AICastRange;
	// walking code
	

	m_tempAbility = rangedAbility;
	if (targetDistSqr < (200 * 200))
	{
		m_tempAbility = meleeAbility;
	}
	if (((m_tempAbility->AICastRange + 100)*(m_tempAbility->AICastRange + 100)) < targetDistSqr)
		return;
	if (GetAbilityState(m_tempAbility)->onCooldownTimer <= 0)
	{
		ChangeNPCAnimation((uint8)EMinionAnimState::MAS_Casting);
		CastAbility(m_tempAbility);
		m_rotateToPlayer = m_tempAbility->rotateTowardsPlayer;
	}
	SetActorRotation(FVector(target->GetActorLocation() - GetActorLocation()).Rotation());
}