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

#include "NpcUsableActor.h"
#include "NpcPawn.h"
#include "PlayerCharacter.h"
#include "Components/InteractionWidgetComponent.h"
#include "Components/SphereComponent.h"
#include "Components/StatForgeComponent.h"
#include "Kismet/GameplayStatics.h"

ANpcUsableActor::ANpcUsableActor()
{
	PrimaryActorTick.bCanEverTick = true;
	RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
	SetRootComponent(RootComponent);
	
	WidgetComponent = CreateDefaultSubobject<UInteractionWidgetComponent>(TEXT("WidgetComponent"));
	WidgetComponent->SetupAttachment(RootComponent);
	
	StatForgeComponent = CreateDefaultSubobject<UStatForgeComponent>("Stat Forge Component");
	
	NpcArriveOverlap = CreateDefaultSubobject<USphereComponent>("Npc Arrive Overlap");
	NpcArriveOverlap->SetupAttachment(RootComponent);
	NpcArriveOverlap->SetSphereRadius(50.f);
	NpcArriveOverlap->SetCollisionEnabled(ECollisionEnabled::Type::QueryOnly);
	NpcArriveOverlap->SetCollisionResponseToAllChannels(ECR_Ignore);
	NpcArriveOverlap->SetCollisionResponseToChannel(ECC_Pawn, ECR_Overlap);
	NpcArriveOverlap->OnComponentBeginOverlap.AddUniqueDynamic(this, &ANpcUsableActor::OnNpcOverlap);
}

void ANpcUsableActor::Occupy(ANpcPawn* InNpc)
{
	if (GetMaxNumOfOccupants() <= UsedByNpcList.Num())
		return;
	
	UsedByNpcList.Add(InNpc);
}

void ANpcUsableActor::ToggleInteractableUI_Implementation(bool bActive)
{
	if (bActive && !IInteractableActorInterface::Execute_IsInteractable(this))
	{
		return;
	}
	
	IInteractableActorInterface::ToggleInteractableUI_Implementation(bActive);
	
	if (WidgetComponent)
	{
		WidgetComponent->ToggleWidget(bActive);
	}
}

void ANpcUsableActor::BeginPlay()
{
	Super::BeginPlay();
	
	PlayerCharRef = Cast<APlayerCharacter>(UGameplayStatics::GetPlayerCharacter(this, 0));
	ensure(PlayerCharRef);
}

void ANpcUsableActor::OnNpcOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
	UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	if (OtherActor && UsedByNpcList.Contains(OtherActor) && !ArrivedNpcs.Contains(OtherActor))
	{
		ArrivedNpcs.AddUnique(Cast<ANpcPawn>(OtherActor));
	}
}

