using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class InputManager : MonoBehaviour
{
    [SerializeField]
    [Range(0f, 10f)]
    private float inputBufferTime = 4f;
    
    public Vector2 moveInput { get; private set; }
    public Vector2 aimInput { get; private set; }

    public bool jumpPerformed{ get; set; }
    public bool attackPerformed { get; set; }
    public bool interactPerformed { get; set; }
    public bool sprintPerformed { get; set; }

    
    private PlayerControlls _playerControlls;
    
    private void OnEnable()
    {
        _playerControlls = new PlayerControlls();
        _playerControlls.Enable();
        
        _playerControlls.Player.Move.Enable();
        _playerControlls.Player.Aim.Enable();
        
        _playerControlls.Player.Sprint.Enable();
        _playerControlls.Player.Sprint.performed += OnSrpint;
        
        _playerControlls.Player.Jump.Enable();
        _playerControlls.Player.Jump.performed += OnJump;

        _playerControlls.Player.Attack.Enable();
        _playerControlls.Player.Attack.performed += OnAtttack;

        _playerControlls.Player.Interact.Enable();
        _playerControlls.Player.Interact.performed += OnInteract;
    }

    private void OnDisable()
    { 
        _playerControlls.Disable();
        
        _playerControlls.Player.Move.Disable();
        _playerControlls.Player.Aim.Disable();
        
        _playerControlls.Player.Sprint.Disable();
        _playerControlls.Player.Sprint.performed -= OnSrpint;

        _playerControlls.Player.Jump.Disable();
        _playerControlls.Player.Jump.performed -= OnJump;

        _playerControlls.Player.Attack.Disable();
        _playerControlls.Player.Attack.performed -= OnAtttack;

        _playerControlls.Player.Interact.Disable();
        _playerControlls.Player.Interact.performed -= OnInteract;
    }
    
    private Coroutine _jumpCoroutine = null;
    private void OnJump(InputAction.CallbackContext context)
    {
        jumpPerformed = true;
        if (_jumpCoroutine != null)
        {
            StopCoroutine(_jumpCoroutine);
        }
        _jumpCoroutine = StartCoroutine(ResetButtonInput(newValue =>
        {
            jumpPerformed = newValue;
            _jumpCoroutine = null;
        }));
    }
    
    private Coroutine _attackCoroutine = null;
    private void OnAtttack(InputAction.CallbackContext context)
    {
        attackPerformed = true;
        
        if (_attackCoroutine != null)
        {
            StopCoroutine(_attackCoroutine);
        }
        _attackCoroutine = StartCoroutine(ResetButtonInput(newValue =>
        {
            attackPerformed = newValue;
            _attackCoroutine = null;
        }));
    }
    
    private Coroutine _sprintCoroutine = null;
    private void OnSrpint(InputAction.CallbackContext context)
    {
        sprintPerformed = true;
        
        if (_sprintCoroutine != null)
        {
            StopCoroutine(_sprintCoroutine);
        }
        _sprintCoroutine = StartCoroutine(ResetButtonInput(newValue =>
        {
            sprintPerformed = newValue;
            _sprintCoroutine = null;
        }));
    }

    private Coroutine _interactCoroutine = null;
    private void OnInteract(InputAction.CallbackContext context)
    {
        interactPerformed = true;
        
        if (_interactCoroutine != null)
        {
            StopCoroutine(_interactCoroutine);
        }
        _interactCoroutine = StartCoroutine(ResetButtonInput(newValue =>
        {
            interactPerformed = newValue;
            _interactCoroutine = null;
        }));
    }
    
    private IEnumerator ResetButtonInput(System.Action<bool> setReset)
    {
        yield return new WaitForSeconds(inputBufferTime);
        setReset(false);
    }

    private void Update()
    {
        if (_playerControlls.Player.Zoom.ReadValue<Vector2>().magnitude > 0.5f)
        {
            print(_playerControlls.Player.Zoom.ReadValue<Vector2>());
        }

        sprintPerformed = _playerControlls.Player.Sprint.ReadValue<float>() > 0.5f;
        moveInput = _playerControlls.Player.Move.ReadValue<Vector2>();
        Vector2 tmp = _playerControlls.Player.Aim.ReadValue<Vector2>();

        tmp.x = Mathf.Clamp(tmp.x, 0f, Screen.width);
        tmp.y = Mathf.Clamp(tmp.y, 0f, Screen.height);
        
        aimInput = tmp;
    }
}