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

#pragma once

#include "CoreMinimal.h"
// #include "DDIWeaponHolder.h"
#include "GameFramework/Character.h"
#include "Logging/LogMacros.h"
#include "DDICharacter.generated.h"

class UInputComponent;
class USkeletalMeshComponent;
class UCameraComponent;
class UInputAction;
struct FInputActionValue;

DECLARE_LOG_CATEGORY_EXTERN(LogTemplateCharacter, Log, All);
// DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FBulletCountUpdatedDelegate, int32, MagazineSize, int32, Bullets);

UCLASS(abstract)
class  ADDICharacter : public ACharacter/*, public IDDIWeaponHolder*/
{
	GENERATED_BODY()

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
	USkeletalMeshComponent* FirstPersonMesh;

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components", meta = (AllowPrivateAccess = "true"))
	UCameraComponent* FirstPersonCamera;

protected:
	/** Name of the first person mesh weapon socket */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category ="Weapons")
	FName FirstPersonWeaponSocket = FName("SOC_hand_r");

	/** Name of the third person mesh weapon socket */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category ="Weapons")
	FName ThirdPersonWeaponSocket = FName("SOC_hand_r");

	/** Max distance to use for aim traces */
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category ="Aim")
	float MaxAimDistance = 10000.0f;

	/** Current HP remaining to this character */
	UPROPERTY(EditAnywhere, Category="Health")
	float CurrentHP = 500.0f;
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
	UInputAction* JumpAction;
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
	UInputAction* MoveAction;
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
	UInputAction* LookAction;
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
	UInputAction* MouseLookAction;
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
	UInputAction* FireAction;
	UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Input")
	UInputAction* SwitchWeaponAction;

	UFUNCTION(BlueprintCallable, Category = "Input")
	virtual void DoJumpStart();
	UFUNCTION(BlueprintCallable, Category = "Input")
	virtual void DoJumpEnd();

	UFUNCTION(BlueprintCallable, Category = "Input")
	virtual void DoMove(float Right, float Froward);

	UFUNCTION(BlueprintCallable, Category = "Input")
	virtual void DoAim(float Yaw, float Pitch);
	
public:
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Pause")
	bool isPaused;
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Pause")
	bool isStoreMenuOpen;
	UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Game Settings")
	float mouseSensitivity;
	
	// UFUNCTION(BlueprintCallable, Category = "Input")
	// void DoStartFiring();
	// UFUNCTION(BlueprintCallable, Category = "Input")
	// void DoStopFiring();
	// UFUNCTION(BlueprintCallable, Category = "Input")
	// void DoSwitchWeapon();


private:
	
protected:
	// TArray<ADDIWeapon*> OwnedWeapons;

	// TObjectPtr<ADDIWeapon> CurrentWeapon;
	virtual void BeginPlay() override;

	
	void MoveInput(const FInputActionValue& value);

	void LookInput(const FInputActionValue& value);
	
	// Called to bind functionality to input
	virtual void SetupPlayerInputComponent( UInputComponent* PlayerInputComponent) override;

	// ADDIWeapon* FindWeaponOfType(TSubclassOf<ADDIWeapon> WeaponClass) const;

public:

	// FBulletCountUpdatedDelegate OnBulletCountUpdated;
	
	// Sets default values for this character's properties
	ADDICharacter();
	// Decontructor for Main Character Class
	virtual ~ADDICharacter();
	virtual float TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCauser) override;

	// USkeletalMeshComponent* GetFirstPersonMesh() const { return FirstPersonMesh; };
	
	UCameraComponent* GetFirstPersonCameraComponent() const {return FirstPersonCamera; };

	//~Begin IShooterWeaponHolder interface

	/** Attaches a weapon's meshes to the owner */
	// virtual void AttachWeaponMeshes(ADDIWeapon* Weapon) override;

	/** Plays the firing montage for the weapon */
	// virtual void PlayFiringMontage(UAnimMontage* Montage) override;

	/** Applies weapon recoil to the owner */
	// virtual void AddWeaponRecoil(float Recoil) override;

	/** Updates the weapon's HUD with the current ammo count */
	// virtual void UpdateWeaponHUD(int CurrentAmmo, int MagazineSize) override;

	/** Calculates and returns the aim location for the weapon */
	// virtual FVector GetWeaponTargetLocation() override;

	/** Gives a weapon of this class to the owner */
	// virtual void AddWeaponClass(const TSubclassOf<ADDIWeapon>& WeaponClass) override;

	/** Activates the passed weapon */
	// virtual void OnWeaponActivated(ADDIWeapon* Weapon) override;

	/** Deactivates the passed weapon */
	// virtual void OnWeaponDeactivated(ADDIWeapon* Weapon) override;

	/** Notifies the owner that the weapon cooldown has expired and it's ready to shoot again */
	// virtual void OnSemiWeaponRefire() override;

	//~End IShooterWeaponHolder interface

};
