using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;
using System.Collections;

public class PlayerInput : MonoBehaviour
{
    public Rigidbody rb;

    [Header("Movement")]
    public float moveSpeed; // Useless ?
    public float maxSpeed;
    public float acceleration;
    public float deceleration;
    public float antiMomentumValue;

    private float movementX;
    private float movementY;
    private bool hasMovedX;
    private bool hasMovedY;

    [Header("ScreenLimitations")]
    public bool canGoOutScreen;
    public float minXborder;
    public float maxXborder;
    public float minYborder;
    public float maxYborder;

    [Header("Shoot")]
    public float shootCooldown;
    public int shootAmount;
    public int shootType;
    public float projectileSpeed;
    public float projectileLifeSpan;
    public float projectileDamage;
    private bool canShoot;
    private bool isShooting;

    [Header("Keybinds")]
    public KeyCode upKey = KeyCode.UpArrow;
    public KeyCode rightKey = KeyCode.RightArrow;
    public KeyCode downKey = KeyCode.DownArrow;
    public KeyCode leftKey = KeyCode.LeftArrow;

    public KeyCode shootKey = KeyCode.LeftShift;
    //public KeyCode crouchKey = KeyCode.LeftControl;
    //public KeyCode attackKey = KeyCode.LeftArrow;

    [Header("Animations")]
    public const string IDLE = "idle";
    public const string LEFT = "leftStay";
    public const string RIGHT = "rightStay";
    public const string ATTACK2 = "Attack2";

    string currentAnimationState;

    [Header("Misc")]
    public Animator animator;



    // ------------------------------------------------------------------ //

    // ================= ## HERE STARTS THE CODE ! ## =================== //

    // ------------------------------------------------------------------ //



    private void Awake()
    {
        animator = GetComponentInChildren<Animator>();
    }
    private void Update()
    {

    }

    // Update is called once per frame
    private void FixedUpdate()
    {
        Move();
    }

    private void MyInput()
    {
        // Start attacking
    }

    // Enable and disable to avoid shooting twice
    private void EnableFire()
    {
        canShoot = true;
        isShooting = false;
    }

    private void Shoot()
    {

    }
    private void Move()
    {
        // Get the pressed input
        MoveStart();

        // Apply the movement
        rb.linearVelocity = new Vector3(movementX, 0, movementY);

        // Change the animation
        SetAnimations();

        // Reduce the speed if needed
        MoveEnd();
    }

    private void MoveStart()
    {
        // Get the pressed Input FIRST.
        hasMovedX = false;
        hasMovedY = false;
        if (Input.GetKey(upKey)) movementY += acceleration;
        if (Input.GetKey(downKey)) movementY -= acceleration;
        if (Input.GetKey(rightKey)) movementX += acceleration;
        if (Input.GetKey(leftKey)) movementX -= acceleration;

        // If the player change direction, accelerate the transition
        if (Input.GetKey(upKey) && movementY < 0) movementY += antiMomentumValue;
        if (Input.GetKey(downKey) && movementY > 0) movementY -= antiMomentumValue;
        if (Input.GetKey(rightKey) && movementX < 0) movementX += antiMomentumValue;
        if (Input.GetKey(leftKey) && movementX > 0) movementX -= antiMomentumValue;

        // Log if the player moved.
        if (Input.GetKey(rightKey) || Input.GetKey(leftKey)) hasMovedX = true;
        if (Input.GetKey(upKey) || Input.GetKey(downKey)) hasMovedY = true;

        // Limit the speed if needed
        if (movementX > maxSpeed) movementX = maxSpeed;
        if (movementY > maxSpeed) movementY = maxSpeed;
        if (movementX < maxSpeed * -1) movementX = maxSpeed * -1;
        if (movementY < maxSpeed * -1) movementY = maxSpeed * -1;
    }

    private void MoveEnd()
    {
        // If the player is still moving, don't reduce his speed

        // Stop the movement if any operation would put the speed in opposite speed
        if (!hasMovedX)
        {
            if (movementX > 0 && movementX - deceleration < 0) movementX = 0;
            if (movementX < 0 && movementX + deceleration > 0) movementX = 0;
        }
        if (!hasMovedY)
        {
            if (movementY > 0 && movementY - deceleration < 0) movementY = 0;
            if (movementY < 0 && movementY + deceleration > 0) movementY = 0;
        }


        // Slow the player down
        if (!hasMovedX)
        {
            if (movementX > 0) movementX -= deceleration;
            if (movementX < 0) movementX += deceleration;
        }
        if (!hasMovedY)
        {
            if (movementY > 0) movementY -= deceleration;
            if (movementY < 0) movementY += deceleration;
        }

    }

    private void SetAnimations()
    {
        if (movementX == 0)
            ChangeAnimationState(IDLE);

        else if (movementX < 0)
            ChangeAnimationState(LEFT);

        else if (movementX > 0)
            ChangeAnimationState(RIGHT);
    }

    public void ChangeAnimationState(string newState)
    {
        // Prevent the same animation from interrupting with itself
        if (currentAnimationState == newState) return;

        // Play the animation 
        currentAnimationState = newState;
        animator.CrossFadeInFixedTime(currentAnimationState, 0.2f);
    }

    public void ApplyInvisibleWalls()
    {

    }

}