using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerMovement : MonoBehaviour
{
    [SerializeField]
    private InputActionReference moveAction;

    [SerializeField]
    private InputActionReference jumpAction;

    [SerializeField]
    private Transform cameraTransform;

    [SerializeField]
    private float speed = 5f;

    [SerializeField]
    private float rotationSpeed = 10f;

    [SerializeField]
    private float gravity = -20f;

    [SerializeField]
    private float jumpHeight = 2f;

    private CharacterController controller;
    private float verticalVelocity;

    void Awake()
    {
        controller =
            GetComponent<CharacterController>();
    }

    void Update()
    {
        Vector2 input =
            moveAction.action.ReadValue<Vector2>();

        Vector3 forward =
            cameraTransform.forward;

        Vector3 right =
            cameraTransform.right;

        forward.y = 0f;
        right.y = 0f;

        forward.Normalize();
        right.Normalize();

        Vector3 direction =
            forward * input.y +
            right * input.x;

        direction =
            Vector3.ClampMagnitude(
                direction,
                1f
            );

        if (direction.sqrMagnitude > 0.001f)
        {
            Quaternion targetRotation =
                Quaternion.LookRotation(direction);

            transform.rotation =
                Quaternion.Slerp(
                    transform.rotation,
                    targetRotation,
                    rotationSpeed *
                    Time.deltaTime
                );
        }

        if (controller.isGrounded &&
            verticalVelocity < 0f)
        {
            verticalVelocity = -2f;
        }

        if (controller.isGrounded &&
            jumpAction.action.WasPressedThisFrame())
        {
            verticalVelocity = Mathf.Sqrt(
                jumpHeight *
                -2f *
                gravity
            );
        }

        verticalVelocity +=
            gravity * Time.deltaTime;

        Vector3 movement =
            direction * speed;

        movement.y = verticalVelocity;

        controller.Move(
            movement *
            Time.deltaTime
        );
    }
}