using System;
using UnityEngine;
using UnityEngine.InputSystem;

public class CharacterController3D : MonoBehaviour
{
    [Header("Movement Settings")]
    [SerializeField] private float playerSpeed = 5.0f;
    [SerializeField] private float jumpHeight = 1.5f;
    [SerializeField] private float gravityValue = -9.81f;
    
    [Header("Sprite Settings")]
    [SerializeField] private SpriteRenderer spriteRenderer;
    [SerializeField] private Sprite forwardSprite;
    [SerializeField] private Sprite backSprite;
    
    private CharacterController _controller;
    private Vector3 _playerVelocity;
    private bool _groundedPlayer;
    [SerializeField] private Camera _mainCamera;
    [SerializeField] private Transform _cameraMainTransform;

    private Vector2 _movementInput;
    private bool _jumpPressed;

    private void Awake()
    {
        _controller = GetComponent<CharacterController>();
        if (spriteRenderer == null)
        {
            spriteRenderer = GetComponentInChildren<SpriteRenderer>();
        }

        if (_cameraMainTransform == null)
        {
            _cameraMainTransform = Camera.main.transform;
        }
    }

    public void OnMove(InputAction.CallbackContext context)
    {
        _movementInput = context.ReadValue<Vector2>();
    }

    public void OnJump(InputAction.CallbackContext context)
    {
        _jumpPressed = context.action.triggered;
    }

    private void LateUpdate()
    {
        Vector3 cameraPosition = _mainCamera.transform.position;
        cameraPosition.y = spriteRenderer.transform.position.y;
        spriteRenderer.transform.LookAt(cameraPosition);
        spriteRenderer.transform.Rotate(0f, 180f, 0f);
    }

    private void Update()
    {
        _groundedPlayer = _controller.isGrounded;
        if (_groundedPlayer && _playerVelocity.y < 0)
        {
            _playerVelocity.y = 0f;
        }
        
        Vector3 camForward = _cameraMainTransform.forward;
        camForward.y = 0;
        camForward.Normalize();
        
        Vector3 camRight = _cameraMainTransform.right;
        camRight.y = 0;
        camRight.Normalize();

        
        Vector3 moveDirection = (camForward * _movementInput.y + camRight * _movementInput.x).normalized;

        _controller.Move(moveDirection * (playerSpeed * Time.deltaTime));

        if (_movementInput.y > 0.1f)
        {
            spriteRenderer.sprite = forwardSprite;
        }
        else if (_movementInput.y < -0.1f)
        {
            spriteRenderer.sprite = backSprite;
        }

        // Jumping
        if (_jumpPressed && _groundedPlayer)
        {
            _playerVelocity.y += Mathf.Sqrt(jumpHeight * -2.0f * gravityValue);
            _jumpPressed = false;
        }

        _playerVelocity.y += gravityValue * Time.deltaTime;
        _controller.Move(_playerVelocity * Time.deltaTime);
    }
}