// Fill out your copyright notice in the Description page of Project Settings.


#include "RingModule.h"

#include "Components/SphereComponent.h"
#include "GameFramework/Character.h"

void ARingModule::BeginPlay()
{
	Super::BeginPlay();

	this->SetActorTickInterval(0.2);
	PlayerChar = GetWorld()->GetFirstPlayerController()->GetCharacter();
	PlayerCam = Cast<UCameraComponent>(PlayerChar->GetComponentByClass(UCameraComponent::StaticClass()));
}

void ARingModule::Tick(float DeltaSeconds)
{
	Super::Tick(DeltaSeconds);

	if (GadgetCantBeUsed()) return;
	CheckForPotentialHackTarget();
}

void ARingModule::CheckForPotentialHackTarget()
{
	FHitResult OutHit;
	FVector LT_Start = PlayerCam->GetComponentLocation();
	FVector LT_End = PlayerCam->GetComponentLocation() + (PlayerCam->GetForwardVector() * DeadBodyCheckDistance);

	//DrawDebugLine(GetWorld(), LT_Start, LT_End, FColor::Red, false, 0.2, 0, 1);

	FCollisionQueryParams QueryParams = FCollisionQueryParams::DefaultQueryParam;
	QueryParams.AddIgnoredActor(PlayerChar);
	if (!GetWorld()->LineTraceSingleByChannel(OutHit, LT_Start, LT_End, ECC_Camera, QueryParams) || !(OutHit.GetActor()->ActorHasTag(FName("Enemy")) && OutHit.GetActor()->ActorHasTag(FName("Dead"))))
	{
		PotentialHackTarget = nullptr;
		DisplayNeedADeadEnemy();
		return;
	}

	if (HackedEnemies.Contains(OutHit.GetActor()->GetUniqueID()))
	{
		PotentialHackTarget = nullptr;
		DisplayAlreadyHacked();
		return;
	}
	
	//DrawDebugLine(GetWorld(), LT_Start, OutHit.ImpactPoint, FColor::Green, false, 0.2, 0, 1);
	PotentialHackTarget = OutHit.GetActor();
	DisplayFoundPotentialTarget();
}


void ARingModule::Activate()
{
	if (GadgetCantBeUsed() || !IsValid(PotentialHackTarget)) return;

	Super::Activate();
	HackedEnemies.Add(PotentialHackTarget->GetUniqueID());
	PlayHackingAnim(GadgetMaxUptime);
}

void ARingModule::FinishedUsing()
{
	SpawnRingingPhoneForAllNearbyEnemies() ? DisplayHackingSuccess() : DisplayHackingFailure();
	Super::FinishedUsing();
	PlayRechargingAnim(CooldownTime);
}

bool ARingModule::SpawnRingingPhoneForAllNearbyEnemies()
{
	FTransform EmptyTransform;
	USphereComponent* SphereCollision = Cast<USphereComponent>(AddComponentByClass(USphereComponent::StaticClass(), false, EmptyTransform, false));
	SphereCollision->SetSphereRadius(AreaOfEffectInMeters * 100, true);

	TArray<AActor*> OverlappingActors;
	TArray<AActor*> EnemiesInRadius;

	SphereCollision->GetOverlappingActors(OverlappingActors, ACharacter::StaticClass());
	for (AActor* OverlappingActor : OverlappingActors)
	{
		if (OverlappingActor->ActorHasTag(FName("Enemy")) && !OverlappingActor->ActorHasTag(FName("Dead"))) EnemiesInRadius.Add(OverlappingActor);
	}

	if (EnemiesInRadius.IsEmpty())
	{
		SphereCollision->DestroyComponent();
		return false;
	}

	FActorSpawnParameters SpawnParams;
	SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
	FAttachmentTransformRules AttachmentRules(EAttachmentRule::SnapToTarget, true);
	for (AActor* Enemy : EnemiesInRadius)
	{
		AActor* SpawnedPhone = GetWorld()->SpawnActor<AActor>(PhoneRingingClass, Enemy->GetActorLocation(), Enemy->GetActorRotation(), SpawnParams);
		SpawnedPhone->AttachToComponent(Enemy->GetRootComponent(), AttachmentRules);
	}
	return true;
}
