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


#include "PickupItem.h"

#include "Components/SphereComponent.h"
#include "Components/StaticMeshComponent.h"
#include "InventoryComponent.h"
#include "ItemDataAsset.h"

#define LOCTEXT_NAMESPACE "PickupItem"

APickupItem::APickupItem()
{
	PrimaryActorTick.bCanEverTick = false;

	Mesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
	SetRootComponent(Mesh);
	// Purement decoratif : c'est la sphere qui porte la collision.
	Mesh->SetCollisionEnabled(ECollisionEnabled::NoCollision);

	// Le trace d'interaction passe par le canal Visibility. On ne bloque QUE
	// ce canal : le pickup reste traversable par le joueur et les projectiles.
	InteractionSphere = CreateDefaultSubobject<USphereComponent>(TEXT("InteractionSphere"));
	InteractionSphere->SetupAttachment(Mesh);
	InteractionSphere->InitSphereRadius(50.f);
	InteractionSphere->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
	InteractionSphere->SetCollisionResponseToAllChannels(ECR_Ignore);
	InteractionSphere->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block);
}

void APickupItem::InitPickup(UItemDataAsset* InItemData, int32 InQuantity, int32 InRemainingUses)
{
	ItemData = InItemData;
	Quantity = FMath::Max(1, InQuantity);
	RemainingUses = InRemainingUses;
}

void APickupItem::OnConstruction(const FTransform& Transform)
{
	Super::OnConstruction(Transform);

	// Confort d'edition : le mesh suit l'objet choisi, tu vois immediatement
	// dans le viewport ce que tu es en train de poser. Vaut aussi a l'execution
	// pour les objets jetes, puisque OnConstruction s'execute a FinishSpawning.
	if (bUseMeshFromItemData && ItemData && ItemData->WorldMesh)
	{
		ItemData->ApplyWorldVisualsTo(Mesh);
	}
}

FText APickupItem::GetInteractionPrompt_Implementation(AActor* Interactor) const
{
	// Interactor ne sert pas ici : ramasser dit la meme chose a tout le monde.
	if (!ItemData)
	{
		return LOCTEXT("PickupUnconfigured", "Unconfigured item");
	}

	if (Quantity > 1)
	{
		return FText::Format(LOCTEXT("PickupPromptStack", "Pick up {0} x{1}"),
			ItemData->DisplayName, FText::AsNumber(Quantity));
	}

	return FText::Format(LOCTEXT("PickupPrompt", "Pick up {0}"), ItemData->DisplayName);
}

bool APickupItem::CanInteract_Implementation(AActor* Interactor) const
{
	// Un pickup sans donnee est une erreur de configuration : on le rend
	// inerte plutot que de laisser le joueur ramasser du vide.
	return ItemData != nullptr;
}

void APickupItem::Interact_Implementation(AActor* Interactor)
{
	UInventoryComponent* Inventory = Interactor ? Interactor->FindComponentByClass<UInventoryComponent>() : nullptr;
	if (!Inventory)
	{
		UE_LOG(LogTemp, Warning, TEXT("APickupItem : %s n'a pas d'UInventoryComponent."), *GetNameSafe(Interactor));
		return;
	}

	const int32 Leftover = Inventory->AddItem(ItemData, Quantity, RemainingUses);
	const int32 Added = Quantity - Leftover;

	// Inventaire plein : on ne detruit surtout pas le tas, on retire seulement
	// ce qui est rentre. Le joueur peut revenir chercher le reste.
	if (Added <= 0)
	{
		if (GEngine)
		{
			GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Red, TEXT("Inventaire plein"));
		}
		return;
	}

	// Retour temporaire, le temps que l'UI d'inventaire existe.
	if (GEngine)
	{
		GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Green,
			FString::Printf(TEXT("+%d %s   (total : %d,  slots : %d/%d)"),
				Added,
				*ItemData->DisplayName.ToString(),
				Inventory->GetItemCount(ItemData),
				Inventory->GetUsedSlotCount(),
				Inventory->GetTotalSlotCount()));
	}

	if (Leftover > 0)
	{
		Quantity = Leftover;
		return;
	}

	Destroy();
}

void APickupItem::OnBeginFocus_Implementation()
{
	if (bHighlightOnFocus)
	{
		Mesh->SetRenderCustomDepth(true);
	}
}

void APickupItem::OnEndFocus_Implementation()
{
	if (bHighlightOnFocus)
	{
		Mesh->SetRenderCustomDepth(false);
	}
}

#undef LOCTEXT_NAMESPACE
