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


#include "DDICharacter.h"

#include "Components/CapsuleComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "OpenConflict/Weapons/Projectiles/ProjectileBase.h"

// Sets default values
ADDICharacter::ADDICharacter()
{
 	// Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	bReplicates = true;
	// bReplicateMovement = true;
				
	CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComponent"));		
	CameraComponent->SetupAttachment(GetMesh(), "headSocket");		
	CameraComponent->SetRelativeLocation(FVector(0.0f, 0.0f, 50.0f));		
	CameraComponent->bUsePawnControlRotation = true;

	HealthComponent = CreateDefaultSubobject<UDDIHealth>(TEXT("HealthComponent"));

	GetCapsuleComponent()->SetCollisionProfileName(TEXT("BlockAllDynamic"));
	GetCapsuleComponent()->SetGenerateOverlapEvents(true);
	GetCapsuleComponent()->SetNotifyRigidBodyCollision(true);


}

// Called when the game starts or when spawned
void ADDICharacter::BeginPlay()
{
	Super::BeginPlay();

	if (GetCapsuleComponent())
	{
		GetCapsuleComponent()->OnComponentHit.AddDynamic(this, &ADDICharacter::OnHit);
	}
	
}

// Called every frame
void ADDICharacter::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

void ADDICharacter::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
	Server_CharacterHit(HitComponent, OtherActor, OtherComp, NormalImpulse, Hit);
}

void ADDICharacter::TakeDamage(int Damage)
{
	HealthComponent->TakeDamage(Damage);
}

bool ADDICharacter::Server_SpawnProjectile_Validate()
{
	return true;
}
void ADDICharacter::Server_SpawnProjectile_Implementation()
{
	FVector Location = GetActorLocation();
	FRotator Rotation = GetActorRotation();
	FVector Dir = GetActorForwardVector();
	
	// GetActorEyesViewPoint(Location, Rotation);

	Location += Dir * 55.f;
	
	if (!ProjectileClass)
	{
		GEngine->AddOnScreenDebugMessage(1, 10.f, FColor::Emerald, "No Projectile Set");
		return;
	}
	
	FActorSpawnParameters SpawnInfo;
	SpawnInfo.Owner = this;
	SpawnInfo.Instigator = GetInstigator();
	GetWorld()->SpawnActor<AActor>(ProjectileClass, Location, Rotation, SpawnInfo);
}

void ADDICharacter::Client_CharacterHit_Implementation()
{
	TakeDamage(10);
	OnDamageTaken();
	
}
bool ADDICharacter::Client_CharacterHit_Validate()
{
	return true;
}
void ADDICharacter::Server_CharacterHit_Implementation(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
	if (AProjectileBase* Projectile = Cast<AProjectileBase>(OtherActor))
	{
		// if (Cast<ADDICharacter>(Projectile->Owner) == this)
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Emerald, "Damage dealt");
		Client_CharacterHit();
	}
}
bool ADDICharacter::Server_CharacterHit_Validate(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
	return true;
}

void ADDICharacter::OnRep_Health()
{
	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, "Health Replicated");
}

void ADDICharacter::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
	DOREPLIFETIME(ADDICharacter, HealthComponent);
}