using UnityEngine;
using UnityEngine.InputSystem;

namespace IStalk.Shared
{
    public class InputProvider : MonoBehaviour
    {
        public static InputProvider Instance { get; private set; }

        [SerializeField] private InputActionAsset _inputActions;

        private InputAction _moveAction;
        private InputAction _lookAction;
        private InputAction _jumpAction;
        private InputAction _sprintAction;
        private InputAction _slideAction;
        private InputAction _dashAction;
        private InputAction _interactAction;
        private InputAction _useItemAction;
        private InputAction _scrollAction;

        public Vector2 Move => _moveAction?.ReadValue<Vector2>() ?? Vector2.zero;
        public Vector2 Look => _lookAction?.ReadValue<Vector2>() ?? Vector2.zero;
        public bool Jump => _jumpAction?.IsPressed() ?? false;
        public bool Sprint => _sprintAction?.IsPressed() ?? false;
        public bool Slide => _slideAction?.IsPressed() ?? false;
        public bool Dash => _dashAction?.WasPressedThisFrame() ?? false;
        public bool Interact => _interactAction?.IsPressed() ?? false;
        public bool InteractDown => _interactAction?.WasPressedThisFrame() ?? false;
        public bool UseItem => _useItemAction?.WasPressedThisFrame() ?? false;
        public float Scroll => _scrollAction?.ReadValue<float>() ?? 0f;

        private void Awake()
        {
            if (Instance != null && Instance != this)
            {
                Destroy(gameObject);
                return;
            }
            Instance = this;
            DontDestroyOnLoad(gameObject);

            if (_inputActions != null)
                BindActions();
            else
                CreateDefaultBindings();
        }

        private void BindActions()
        {
            var gameplay = _inputActions.FindActionMap("Gameplay");
            if (gameplay == null) return;

            _moveAction = gameplay.FindAction("Move");
            _lookAction = gameplay.FindAction("Look");
            _jumpAction = gameplay.FindAction("Jump");
            _sprintAction = gameplay.FindAction("Sprint");
            _slideAction = gameplay.FindAction("Slide");
            _dashAction = gameplay.FindAction("Dash");
            _interactAction = gameplay.FindAction("Interact");
            _useItemAction = gameplay.FindAction("UseItem");
            _scrollAction = gameplay.FindAction("Scroll");

            _inputActions.Enable();
        }

        private void CreateDefaultBindings()
        {
            _moveAction = new InputAction("Move", InputActionType.Value);
            _moveAction.AddCompositeBinding("2DVector")
                .With("Up", "<Keyboard>/w")
                .With("Down", "<Keyboard>/s")
                .With("Left", "<Keyboard>/a")
                .With("Right", "<Keyboard>/d");
            _moveAction.AddBinding("<Gamepad>/leftStick");

            _lookAction = new InputAction("Look", InputActionType.Value);
            _lookAction.AddBinding("<Mouse>/delta");
            _lookAction.AddBinding("<Gamepad>/rightStick");

            _jumpAction = new InputAction("Jump", InputActionType.Button);
            _jumpAction.AddBinding("<Keyboard>/space");
            _jumpAction.AddBinding("<Gamepad>/buttonSouth");

            _sprintAction = new InputAction("Sprint", InputActionType.Button);
            _sprintAction.AddBinding("<Keyboard>/leftShift");
            _sprintAction.AddBinding("<Gamepad>/leftStickPress");

            _slideAction = new InputAction("Slide", InputActionType.Button);
            _slideAction.AddBinding("<Keyboard>/leftCtrl");
            _slideAction.AddBinding("<Gamepad>/buttonEast");

            _dashAction = new InputAction("Dash", InputActionType.Button);
            _dashAction.AddBinding("<Keyboard>/e");
            _dashAction.AddBinding("<Gamepad>/leftShoulder");

            _interactAction = new InputAction("Interact", InputActionType.Button);
            _interactAction.AddBinding("<Keyboard>/f");
            _interactAction.AddBinding("<Gamepad>/buttonWest");

            _useItemAction = new InputAction("UseItem", InputActionType.Button);
            _useItemAction.AddBinding("<Keyboard>/q");
            _useItemAction.AddBinding("<Gamepad>/rightShoulder");

            _scrollAction = new InputAction("Scroll", InputActionType.Value);
            _scrollAction.AddBinding("<Mouse>/scroll/y");

            _moveAction.Enable();
            _lookAction.Enable();
            _jumpAction.Enable();
            _sprintAction.Enable();
            _slideAction.Enable();
            _dashAction.Enable();
            _interactAction.Enable();
            _useItemAction.Enable();
            _scrollAction.Enable();
        }

        private void OnDestroy()
        {
            if (_inputActions == null)
            {
                _moveAction?.Dispose();
                _lookAction?.Dispose();
                _jumpAction?.Dispose();
                _sprintAction?.Dispose();
                _slideAction?.Dispose();
                _dashAction?.Dispose();
                _interactAction?.Dispose();
                _useItemAction?.Dispose();
                _scrollAction?.Dispose();
            }
        }
    }
}
