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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Interface/InteractableActorInterface.h"
#include "NpcUsableActor.generated.h"

class APlayerCharacter;
class USphereComponent;
class UStatForgeComponent;
class ANpcPawn;
class UInteractionWidgetComponent;

UENUM(BlueprintType)
enum class EInteractAnimAction : uint8
{
	Idle,
	Sitting
};

UCLASS()
class FAYE_API ANpcUsableActor : public AActor, public IInteractableActorInterface
{
	GENERATED_BODY()

public:
	ANpcUsableActor();
	
	UFUNCTION(BlueprintCallable, Category = "Usable Actor")
	void Occupy(ANpcPawn* InNpc);
	
	UFUNCTION(BlueprintPure, Category = "Usable Actor")
	bool IsOccupied() const { return UsedByNpcList.Num() >= GetMaxNumOfOccupants(); }
	
	UFUNCTION(BlueprintPure, Category = "Usable Actor")
	int32 GetNumOfOccupants() const { return UsedByNpcList.Num(); }
	
	UFUNCTION(BlueprintPure, Category = "Usable Actor")
	ANpcPawn* GetNextOccupant() const { return UsedByNpcList.IsEmpty()? nullptr : UsedByNpcList.Last(); }
	
	UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
	FVector GetNpcArriveLocation();
	virtual FVector GetNpcArriveLocation_Implementation() { return FVector(); }
	
	UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
	EInteractAnimAction GetInteractAnimAction();
	virtual EInteractAnimAction GetInteractAnimAction_Implementation() { return EInteractAnimAction::Idle; }
	
	UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
	int32 GetMaxNumOfOccupants() const;
	virtual int32 GetMaxNumOfOccupants_Implementation() const { return 1; }
	
	UFUNCTION(BlueprintPure, BlueprintCallable)
	bool DidAllOccupantsArrive() const {return UsedByNpcList.Num() == ArrivedNpcs.Num();}
	
	UFUNCTION(BlueprintPure, BlueprintCallable)
	APlayerCharacter* GetCachedPlayerCharacter() const { return PlayerCharRef; }
	
	/*--- INTERACTION START ---*/
	
	virtual FText GetInteractionText_Implementation() const override { return NSLOCTEXT("Faye", "UsableActorInteract", "Interact"); }
	virtual bool IsInteractable_Implementation() const override { return true; }
	virtual void ToggleInteractableUI_Implementation(bool bActive) override;
	
	/*--- INTERACTION END  ---*/

protected:
	
	UPROPERTY()
	TArray<ANpcPawn*> UsedByNpcList;
	UPROPERTY()
	TArray<ANpcPawn*> ArrivedNpcs;
	
	UPROPERTY()
	TObjectPtr<APlayerCharacter> PlayerCharRef = nullptr;
	
	virtual void BeginPlay() override;
	
	UFUNCTION()
	void OnNpcOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult);
	
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
	UInteractionWidgetComponent* WidgetComponent;
	
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess = "true"))
	TObjectPtr<UStatForgeComponent> StatForgeComponent;
	
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, meta=(AllowPrivateAccess = "true"))
	TObjectPtr<USphereComponent> NpcArriveOverlap; 
};
