// Copyright ExByte Studios. Item Interaction Ecosystem.

#pragma once

#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "InteractionTraceComponent.generated.h"

class UInteractableComponent;

DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnInteractionTargetChanged, AActor*, NewTarget, UInteractableComponent*, NewInteractable);

/**
 * Local-only aim trace that finds the best interactable under the crosshair
 * (section 8.2). Runs only on the owning client; the result drives the prompt UI
 * and is what the player confirms - never trusted by the server.
 */
UCLASS(ClassGroup = (Interaction), meta = (BlueprintSpawnableComponent))
class ITEMINTERACTION_API UInteractionTraceComponent : public UActorComponent
{
	GENERATED_BODY()

public:
	UInteractionTraceComponent();

	virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;

	/** Fires the trace once and updates CurrentTarget. */
	UFUNCTION(BlueprintCallable, Category = "Interaction")
	void TickTrace();

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Interaction")
	float TraceDistance = 300.f;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Interaction")
	float TraceRadius = 12.f;

	/** Trace channel; defaults to Visibility. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Interaction")
	TEnumAsByte<ECollisionChannel> TraceChannel = ECC_Visibility;

	UPROPERTY(BlueprintReadOnly, Category = "Interaction")
	TObjectPtr<AActor> CurrentTarget = nullptr;

	UPROPERTY(BlueprintReadOnly, Category = "Interaction")
	TObjectPtr<UInteractableComponent> CurrentInteractable = nullptr;

	UPROPERTY(BlueprintReadOnly, Category = "Interaction")
	FVector LastHitLocation = FVector::ZeroVector;

	UPROPERTY(BlueprintReadOnly, Category = "Interaction")
	FVector LastHitNormal = FVector::ZeroVector;

	UPROPERTY(BlueprintAssignable, Category = "Interaction")
	FOnInteractionTargetChanged OnTargetChanged;

private:
	bool GetViewPoint(FVector& OutLocation, FRotator& OutRotation) const;
	void SetTarget(AActor* NewTarget, UInteractableComponent* NewInteractable);
};
