using System;
using UnityEngine;
using UnityEngine.XR;

namespace _PROJECT.NewHandPresence
{
    public class XRControllerAnimator : MonoBehaviour
    {
        public Animator _animator { get; set; }

        private static readonly int JoystickX = Animator.StringToHash("JoystickX");
        private static readonly int JoystickY = Animator.StringToHash("JoystickY");
        private static readonly int Trigger = Animator.StringToHash("Trigger");
        private static readonly int Grip = Animator.StringToHash("Grip");
        private static readonly int ButtonA = Animator.StringToHash("ButtonA");
        private static readonly int ButtonB = Animator.StringToHash("ButtonB");
        private static readonly int TrackpadX = Animator.StringToHash("TrackpadX");
        private static readonly int TrackpadY = Animator.StringToHash("TrackpadY");
        private static readonly int MenuButton = Animator.StringToHash("MenuButton");

        public void UpdateGrip(float grip)
        {
            _animator.SetFloat(Grip, grip);
        }

        public void UpdateTrigger(float trigger)
        {
            _animator.SetFloat(Trigger, trigger);
        }

        private void UpdateButtonA(float buttonA)
        {
            _animator.SetFloat(ButtonA, buttonA);
        }

        private void UpdateButtonB(float buttonB)
        {
            _animator.SetFloat(ButtonB, buttonB);
        }

        private void UpdateJoystick(Vector2 joystick)
        {
            _animator.SetFloat(JoystickX, joystick.x);
            _animator.SetFloat(JoystickY, joystick.y);
        }

        private void UpdateTrackpad(Vector2 trackpad)
        {
            _animator.SetFloat(TrackpadX, trackpad.x);
            _animator.SetFloat(TrackpadY, trackpad.y);
        }

        public void UpdateMenuButton(float menuButton)
        {
            _animator.SetFloat(MenuButton, menuButton);
        }

        public void Start()
        {
            _animator = GetComponent<Animator>();
            _animator.logWarnings = false;
        }

        public void UpdateAnimations(InputDevice targetDevice)
        {
            // Float
            UpdateFeatureValue(targetDevice, CommonUsages.grip, UpdateGrip);
            UpdateFeatureValue(targetDevice, CommonUsages.trigger, UpdateTrigger);
            
            // Vector2
            // Vive primary is trackpad, others are joystick, so we update both
            UpdateFeatureValue(targetDevice, CommonUsages.primary2DAxis, UpdateJoystick);
            UpdateFeatureValue(targetDevice, CommonUsages.primary2DAxis, UpdateTrackpad);
            
            // Bool
            UpdateFeatureValue(targetDevice, CommonUsages.primaryButton, (pressed) => UpdateButtonA(pressed ? 1f : 0f));
            UpdateFeatureValue(targetDevice, CommonUsages.secondaryButton, (pressed) => UpdateButtonB(pressed ? 1f : 0f));
            UpdateFeatureValue(targetDevice, CommonUsages.menuButton, (pressed) => UpdateButtonB(pressed ? 1f : 0f));
        }
        
        private void UpdateFeatureValue(InputDevice targetDevice, InputFeatureUsage<bool> feature, Action<bool> updateAction)
        {
            if (targetDevice.TryGetFeatureValue(feature, out bool value))
            {
                updateAction(value);
            }
        }
        
        private void UpdateFeatureValue(InputDevice targetDevice, InputFeatureUsage<float> feature, Action<float> updateAction)
        {
            if (targetDevice.TryGetFeatureValue(feature, out float value))
            {
                updateAction(value);
            }
        }
        
        private void UpdateFeatureValue(InputDevice targetDevice, InputFeatureUsage<Vector2> feature, Action<Vector2> updateAction)
        {
            if (targetDevice.TryGetFeatureValue(feature, out Vector2 value))
            {
                updateAction(value);
            }
        }



    }
}