#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "InputActionValue.h"
#include "PS_Editor_Pawn.generated.h"

class UCameraComponent;
class USpringArmComponent;
class UInputAction;
class UInputMappingContext;

/**
 * Camera modes for the editor pawn.
 */
UENUM(BlueprintType)
enum class EPS_Editor_CameraMode : uint8
{
	/** Default mode - cursor visible, ZQSD/arrows still move. */
	Idle,
	/** Left-click held: mouse Y = forward/back on horizontal plane, mouse X = yaw rotation. */
	Pan,
	/** Right-click held: full free look + ZQSD movement. */
	Fly,
	/** Alt + left-click held: orbit around focal point. */
	Orbit
};

/**
 * Editor camera pawn mimicking UE viewport navigation.
 *
 * Controls:
 * - Left-click held: Pan (mouse Y = move forward/back, mouse X = yaw)
 * - Right-click held: Fly (ZQSD + free mouse look)
 * - Alt + left-click held: Orbit around focal point
 * - Middle-click held: Orbit around focal point (alternative)
 * - ZQSD / Arrows: Always active movement
 * - E/A: Up/Down
 * - Mouse wheel: Zoom / adjust fly speed
 */
UCLASS()
class PS_EDITOR_API APS_Editor_Pawn : public APawn
{
	GENERATED_BODY()

public:
	APS_Editor_Pawn();

	virtual void SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) override;
	virtual void Tick(float DeltaTime) override;

protected:
	virtual void BeginPlay() override;

	// ---- Components ----

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera")
	TObjectPtr<USceneComponent> RootScene;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera")
	TObjectPtr<USpringArmComponent> SpringArm;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera")
	TObjectPtr<UCameraComponent> Camera;

	// ---- Camera Settings ----

	/** Base movement speed in fly mode (cm/s). */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Fly")
	float FlySpeed = 1000.0f;

	/** Minimum fly speed. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Fly")
	float FlySpeedMin = 100.0f;

	/** Maximum fly speed. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Fly")
	float FlySpeedMax = 10000.0f;

	/** Mouse look sensitivity. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Fly")
	float LookSensitivity = 2.5f;

	/** Speed change per scroll tick. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Fly")
	float FlySpeedScrollStep = 200.0f;

	/** Pan speed multiplier (left-click drag forward/back). */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Pan")
	float PanSpeed = 5.0f;

	/** Pan yaw sensitivity (left-click drag left/right). */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Pan")
	float PanYawSensitivity = 1.0f;

	/** Orbit distance from focal point. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Orbit")
	float OrbitDistance = 500.0f;

	/** Orbit zoom step per scroll tick. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Orbit")
	float OrbitZoomStep = 50.0f;

	/** Minimum orbit distance. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Orbit")
	float OrbitDistanceMin = 50.0f;

	/** Maximum orbit distance. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Orbit")
	float OrbitDistanceMax = 5000.0f;

	/** Orbit rotation sensitivity. */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Camera|Orbit")
	float OrbitSensitivity = 1.0f;

	// ---- State ----

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera")
	EPS_Editor_CameraMode CameraMode = EPS_Editor_CameraMode::Idle;

	/** The point in world space the orbit camera rotates around. */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Camera|Orbit")
	FVector OrbitFocalPoint = FVector::ZeroVector;

private:
	// ---- Input Actions (created at runtime) ----
	UPROPERTY()
	TObjectPtr<UInputMappingContext> EditorMappingContext;

	UPROPERTY()
	TObjectPtr<UInputAction> IA_Move;

	UPROPERTY()
	TObjectPtr<UInputAction> IA_Look;

	UPROPERTY()
	TObjectPtr<UInputAction> IA_Scroll;

	UPROPERTY()
	TObjectPtr<UInputAction> IA_LeftClick;

	UPROPERTY()
	TObjectPtr<UInputAction> IA_RightClick;

	UPROPERTY()
	TObjectPtr<UInputAction> IA_MiddleClick;

	/** Is the Alt key currently held down. */
	bool bAltHeld = false;

	// ---- Input Handlers ----
	void HandleMove(const FInputActionValue& Value);
	void HandleLook(const FInputActionValue& Value);
	void HandleScroll(const FInputActionValue& Value);
	void HandleLeftClickStarted(const FInputActionValue& Value);
	void HandleLeftClickCompleted(const FInputActionValue& Value);
	void HandleRightClickStarted(const FInputActionValue& Value);
	void HandleRightClickCompleted(const FInputActionValue& Value);
	void HandleMiddleClickStarted(const FInputActionValue& Value);
	void HandleMiddleClickCompleted(const FInputActionValue& Value);

	// ---- Helpers ----
	void CreateInputActions();
	void SetCameraMode(EPS_Editor_CameraMode NewMode);
	void UpdateCursorVisibility();
	void ComputeOrbitFocalPoint();

	/** Current pitch accumulated during orbit (clamped). */
	float OrbitPitch = 0.0f;
	/** Current yaw accumulated during orbit. */
	float OrbitYaw = 0.0f;
};
