using System.Collections;
using System.Collections.Generic;
using Cinemachine;
using DG.Tweening;
using UnityEngine;

public class PlayerMovementController : MonoBehaviour
{
    public bool CanMove { get; private set; } = true;

    [Header("Movement Parameters")]
    [SerializeField] private float moveSpeed = 5f;
    [SerializeField] private float turnSpeed = 5f;
    [SerializeField] private float gravity = 10f;
    [SerializeField] private float jumpForce = 5f;


    [Header("Look Parameters")]
    [SerializeField] private CinemachineFreeLook virtualCamera;
    [SerializeField, Range(1, 10)] private float lookSensitivity = 2f;
    [SerializeField, Range(1, 120)] private float lookClamp = 85f;

    private Camera playerCamera;
    // private CharacterController characterController;
    private Rigidbody rb;

    private Vector3 moveDirection;
    private Vector2 currentInput;

    private Vector3 moveDirectionWhenJump;

    private void Awake()
    {
        rb = GetComponent<Rigidbody>();
        playerCamera = GetComponentInChildren<Camera>();
        // characterController = GetComponent<CharacterController>();
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
    }

    private void Update()
    {
        if (CanMove)
        {
            HandleLook();
            HandleJump();
            HandleRotation();
            HandleMovement();
        }
    }

    private void HandleRotation()
    {
        var horizontal = Input.GetAxisRaw("Horizontal");
        var _currentInput = new Vector2(0f, Time.deltaTime * turnSpeed * horizontal);
        var euler = transform.rotation.eulerAngles;
        euler.z = -45 * horizontal;
        transform.DORotate(euler, .6f);

        if (_currentInput != Vector2.zero)
        {
            transform.eulerAngles += new Vector3(0f, _currentInput.y, 0f);
        }
        virtualCamera.m_XAxis.Value += _currentInput.y / 10f;
    }


    private void HandleMovement()
    {
        currentInput = new Vector2(moveSpeed * Input.GetAxisRaw("Vertical"), 0f);
        Vector3 newMoveDirection;


        newMoveDirection = transform.TransformDirection(Vector3.forward) * currentInput.x;

        moveDirection.x = newMoveDirection.x;
        moveDirection.z = newMoveDirection.z;

        Vector2 moveDirInXZ = new Vector2(moveDirection.x, moveDirection.z);
        moveDirInXZ = moveDirInXZ.normalized * Mathf.Clamp(moveDirInXZ.magnitude, 0, moveSpeed);
        moveDirection.x = moveDirInXZ.x;
        moveDirection.z = moveDirInXZ.y;
        Debug.Log(moveDirection);
        // characterController.Move(moveDirection * Time.deltaTime);
        if (moveDirection != Vector3.zero)
        {
            rb.Move(transform.position + (moveDirection * Time.deltaTime), transform.rotation);
        }

        if (moveDirection.y < -0.1f)
        {
            var euler = transform.rotation.eulerAngles;
            euler.x = 45;
            transform.DORotate(euler, .6f);
        }
        else
        {
            var euler = transform.rotation.eulerAngles;
            euler.x = 0;
            transform.DORotate(euler, .6f);
        }
    }

    private void HandleJump()
    {

        if (transform.position.y > 0.05f)
        {
            moveDirection.y -= gravity * Time.deltaTime;
            moveDirection.y = Mathf.Clamp(moveDirection.y, -gravity, jumpForce);
        }

        bool isJumped = Input.GetButton("Jump");
        if (isJumped)
        {
            moveDirectionWhenJump = moveDirection;
            if (moveDirection.y < 0)
                moveDirection.y += 2 * jumpForce * Time.deltaTime;

            moveDirection.y += jumpForce * Time.deltaTime;
            moveDirection.y += gravity * Time.deltaTime; // Gravity is still applied when jumping
            moveDirection.y = Mathf.Clamp(moveDirection.y, -gravity, jumpForce);
        }
        else
        {
            if (moveDirection.y > 0)
            {
                moveDirection.y -= gravity * 3 * Time.deltaTime;
            }
        }
    }

    private void HandleLook()
    {

        // var rotY = Input.GetAxis("Mouse Y") * lookSensitivity;
        // var rotX = Input.GetAxis("Mouse X") * lookSensitivity;

        // var eulerAngles = virtualCamera.GetCinemachineComponent<CinemachineTransposer>().m_FollowOffset;

        // Debug.Log(eulerAngles);

        // virtualCamera.GetCinemachineComponent<CinemachineTransposer>().m_FollowOffset = new Vector3(eulerAngles.x + rotX, eulerAngles.y + rotY, 0f);



    }

}