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

#include "Shotgun.h"
#include "GameJamTemplate.h"
#include "Actors/Target.h"
#include "Actors/Ammo.h"
#include "Spawners/AmmoSpawner.h"
#include "Kismet/GameplayStatics.h"
#include "Sound/SoundCue.h"
// Paper2D plugin headers.
#include "PaperFlipbook.h"
#include "PaperFlipbookComponent.h"
#include "Camera/CameraComponent.h"
#include "SoundManager.h"
#include "JamGameMode.h"

AShotgun::AShotgun() :
ShotgunName(GetName())
{
	PrimaryActorTick.bCanEverTick = true;

	RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));

	CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComponent"));
	CameraComponent->SetupAttachment(RootComponent);

	PaperFlipbook = CreateDefaultSubobject<UPaperFlipbookComponent>(TEXT("PaperFlipbook"));
	PaperFlipbook->SetupAttachment(RootComponent);

	LocalAmmoSpawner = nullptr;
	SoundManager = nullptr;
}

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

	AGameModeBase* GameModeBase = UGameplayStatics::GetGameMode(GetWorld());

	if (GameModeBase != nullptr)
	{
		JamGameMode = Cast<AJamGameMode>(GameModeBase);

		if (JamGameMode != nullptr)
		{
			SoundManager = JamGameMode->GetSoundManager();
		}
	}

	PlayerController = (APlayerController*)GetController();
	if (PlayerController == nullptr)
	{
		UE_LOG(LogGameJam, Fatal,
			TEXT("[%s] Could not get the pawn's player controller"),
			*ShotgunName);
	}
	
	LocalAmmoSpawner = (AAmmoSpawner*)UGameplayStatics::GetActorOfClass(GetWorld(), AAmmoSpawner::StaticClass());
	if (LocalAmmoSpawner == nullptr)
	{
		UE_LOG(LogGameJam, Log,
			TEXT("[%s] Could not get the Ammo Spawner"),
			*ShotgunName);
	}

	AmmoRound = nullptr;
	LeftRoundShot = false;
	RightRoundShot = false;
}

void AShotgun::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	if (LocalAmmoSpawner != nullptr)
	{
		if (AmmoRound != nullptr && !LocalAmmoSpawner->GetIsRoundRunning())
		{
			AmmoRound->Destroy();
		}

		if (!LocalAmmoSpawner->GetIsRoundRunning())
		{
			if (PaperFlipbook->IsVisible())
				PaperFlipbook->SetVisibility(false);
		}
		else
		{
			if (!PaperFlipbook->IsVisible())
				PaperFlipbook->SetVisibility(true);
		}
	}
}

void AShotgun::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
	Super::SetupPlayerInputComponent(PlayerInputComponent);
	PlayerInputComponent->BindAction("LeftMouseButton", IE_Pressed, this, &AShotgun::OnLeftMouseButtonEvent);
	PlayerInputComponent->BindAction("RightMouseButton", IE_Pressed, this, &AShotgun::OnRightMouseButtonEvent);

	PlayerInputComponent->BindAction("Num1Pressed", IE_Pressed, this, &AShotgun::OnNum1PressedButtonEvent);
	PlayerInputComponent->BindAction("Num2Pressed", IE_Pressed, this, &AShotgun::OnNum2PressedButtonEvent);
	PlayerInputComponent->BindAction("Num3Pressed", IE_Pressed, this, &AShotgun::OnNum3PressedButtonEvent);
}

FHitResult AShotgun::GetHitResult()
{
	FHitResult HitResult;
	PlayerController->GetHitResultUnderCursorByChannel(
		ETraceTypeQuery::TraceTypeQuery_MAX, true, HitResult);
	return HitResult;
}

void AShotgun::OnLeftMouseButtonEvent()
{

	if (LocalAmmoSpawner != nullptr)
	{
		if (LocalAmmoSpawner->GetIsRoundRunning()) Shoot(true);
	}
}

void AShotgun::OnRightMouseButtonEvent()
{

	if (LocalAmmoSpawner != nullptr)
	{
		if (LocalAmmoSpawner->GetIsRoundRunning()) Shoot(false);
	}
}

void AShotgun::Reload(AAmmo* NewPair)
{

	if (LocalAmmoSpawner != nullptr)
	{
		if (AmmoRound != nullptr)
		{
			AmmoRound->Destroy();
		}

		AmmoRound = NewPair;
		AmmoRound->SetActorLocation(FVector(AmmoRound->GetActorLocation().X, AmmoRound->GetActorLocation().Y, AmmoRound->GetActorLocation().Z + 150));
		AmmoRound->SetActorRotation(LocalAmmoSpawner->GetActorRotation());
		LeftRoundShot = true;
		RightRoundShot = true;
	}
}

void AShotgun::OnNum1PressedButtonEvent()
{

	if (LocalAmmoSpawner != nullptr)
	{
		if (LocalAmmoSpawner->GetIsRoundRunning()) Reload(LocalAmmoSpawner->GetAmmoItter(1));
	}
}
void AShotgun::OnNum2PressedButtonEvent()
{

	if (LocalAmmoSpawner != nullptr)
	{
		if (LocalAmmoSpawner->GetIsRoundRunning()) Reload(LocalAmmoSpawner->GetAmmoItter(2));
	}
}
void AShotgun::OnNum3PressedButtonEvent()
{

	if (LocalAmmoSpawner != nullptr)
	{
		if (LocalAmmoSpawner->GetIsRoundRunning()) Reload(LocalAmmoSpawner->GetAmmoItter(3));
	}
}

void AShotgun::Shoot(bool IsLeftRound)
{
	FHitResult HitResult = GetHitResult();
	AActor* HitTarget = HitResult.GetActor();

	if (HitTarget != nullptr)
	{
		UE_LOG(LogGameJam, Log, TEXT("Left clicked on actor '%s'"), *(HitTarget->GetName()));
		ATarget* LTarget = Cast<ATarget>(HitTarget);

		if (LTarget != nullptr)
		{
			if (IsLeftRound)
			{
				if (LeftRoundShot)
				{
					if (AmmoRound->GetLeftRound()->GetRoundColor() == EAmmoColour::Red)
					{
						LTarget->Shoot(AmmoRound->GetLeftRound()->GetSpread() ? 500 : 0);
						LeftRoundShot = false;
						AmmoRound->GetLeftPaperFlipbook()->SetFlipbook(AmmoRound->GetLeftRound()->GetSpread() ? EmptySpreadAmmo : EmptyAmmo);
					}
					else 
					{
						LTarget->Flip(false, AmmoRound->GetLeftRound()->GetSpread() ? 500 : 0);
						LeftRoundShot = false;
						AmmoRound->GetLeftPaperFlipbook()->SetFlipbook(AmmoRound->GetLeftRound()->GetSpread() ? EmptySpreadAmmo : EmptyAmmo);
					}
				}
				else
				{
					if (SoundManager != nullptr)
					{
						SoundManager->PlaySound(EGameSoundType::Effect, AmmoEmptySound, GetActorLocation());
					}
				}
			}
			else
			{
				if (RightRoundShot)
				{
					if (AmmoRound->GetRightRound()->GetRoundColor() == EAmmoColour::Red)
					{
						LTarget->Shoot(AmmoRound->GetRightRound()->GetSpread() ? 500 : 0);
						RightRoundShot = false;
						AmmoRound->GetRightPaperFlipbook()->SetFlipbook(AmmoRound->GetRightRound()->GetSpread() ? EmptySpreadAmmo : EmptyAmmo);
					}
					else
					{
						LTarget->Flip(false, AmmoRound->GetRightRound()->GetSpread() ? 500 : 0);
						RightRoundShot = false;
						AmmoRound->GetRightPaperFlipbook()->SetFlipbook(AmmoRound->GetRightRound()->GetSpread()? EmptySpreadAmmo: EmptyAmmo);
					}
				}
				else
				{
					if (SoundManager != nullptr)
					{
						SoundManager->PlaySound(EGameSoundType::Effect, AmmoEmptySound, GetActorLocation());
					}
				}
			}
			UE_LOG(LogGameJam, Log, TEXT("Target Actor clicked '%s'"), *(LTarget->GetName()));
		}
		else
		{
			if (IsLeftRound)
			{
				if (LeftRoundShot)
				{
					AmmoRound->GetLeftPaperFlipbook()->SetFlipbook(AmmoRound->GetLeftRound()->GetSpread() ? EmptySpreadAmmo : EmptyAmmo);
					if (SoundManager != nullptr)
					{
						SoundManager->PlaySound(EGameSoundType::Effect, TargetMissedSound, GetActorLocation());
					}
					LeftRoundShot = false;
				}
				else
				{
					if (SoundManager != nullptr)
					{
						SoundManager->PlaySound(EGameSoundType::Effect, AmmoEmptySound, GetActorLocation());
					}
				}
			}
			else
			{
				if (RightRoundShot)
				{
					AmmoRound->GetRightPaperFlipbook()->SetFlipbook(AmmoRound->GetRightRound()->GetSpread() ? EmptySpreadAmmo : EmptyAmmo);
					if (SoundManager != nullptr)
					{
						SoundManager->PlaySound(EGameSoundType::Effect, TargetMissedSound, GetActorLocation());
					}
					RightRoundShot = false;
				}
				else
				{
					if (SoundManager != nullptr)
					{
						SoundManager->PlaySound(EGameSoundType::Effect, AmmoEmptySound, GetActorLocation());
					}
				}
			}
		}
	}
}