using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;

namespace UnityXR
{
    public class HandPresence : MonoBehaviour
    {
        public bool showController;
        public InputDeviceCharacteristics controllerCharacteristics;
        public List<GameObject> controllerPrefabs;
        public GameObject handModelPrefab;

        private InputDevice _targetDevice;
        private GameObject _spawnedController;
        private GameObject _spawnedHandModel;
        private Animator _handAnimator;

        private static readonly int Trigger = Animator.StringToHash("Trigger");
        private static readonly int Grip = Animator.StringToHash("Grip");

        private void TryInitialize()
        {
            var devices = new List<InputDevice>();
            InputDevices.GetDevicesWithCharacteristics(controllerCharacteristics, devices);
            if (devices.Count <= 0) return;

            _targetDevice = devices[0];
            GameObject prefab = controllerPrefabs.Find(controller => controller.name == _targetDevice.name);
            _spawnedController = Instantiate(prefab ? prefab : controllerPrefabs[0], transform);

            _spawnedHandModel = Instantiate(handModelPrefab, transform);
            _handAnimator = _spawnedHandModel.GetComponent<Animator>();
        }

        private void UpdateHandAnimation()
        {
            if (_targetDevice.TryGetFeatureValue(CommonUsages.trigger, out float triggerValue))
            {
                _handAnimator.SetFloat(Trigger, triggerValue);
            }
            else
            {
                _handAnimator.SetFloat(Trigger, 0);
            }

            if (_targetDevice.TryGetFeatureValue(CommonUsages.grip, out float gripValue))
            {
                _handAnimator.SetFloat(Grip, gripValue);
            }
            else
            {
                _handAnimator.SetFloat(Grip, 0);
            }
        }

        // Update is called once per frame
        void Update()
        {
            if (!_targetDevice.isValid)
            {
                TryInitialize();
            }
            else
            {
                if (showController)
                {
                    _spawnedHandModel.SetActive(false);
                    _spawnedController.SetActive(true);
                }
                else
                {
                    _spawnedHandModel.SetActive(true);
                    _spawnedController.SetActive(false);
                    UpdateHandAnimation();
                }
            }
        }
    }
}