using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
using Valve.VR;
using Debug = UnityEngine.Debug;

namespace Tracking
{
    public class TrackerIndexManager : MonoBehaviour
    {
        private IEnumerable<IViveTracker> trackers;

        private void OnEnable()
        {
            SteamVR_Events.DeviceConnected.Listen(OnDeviceConnected);
            trackers = GetComponentsInChildren<IViveTracker>();
        }

        private void OnDeviceConnected(int index, bool connected)
        {
            if (index < 0) return;
            if (!connected || OpenVR.System == null) return;

            var deviceClass = OpenVR.System.GetTrackedDeviceClass((uint) index);
            if (deviceClass != ETrackedDeviceClass.GenericTracker) return;

            SetIndexForSerialNumber(index);
            SetBatteryLevelForIndex(index);
        }

        private void SetBatteryLevelForIndex(int index)
        {
            var error = ETrackedPropertyError.TrackedProp_Success;
            var batteryLevel = OpenVR.System.GetFloatTrackedDeviceProperty((uint) index,
                ETrackedDeviceProperty.Prop_DeviceBatteryPercentage_Float, ref error);
            
            if (error != ETrackedPropertyError.TrackedProp_Success)
            {
                Debug.LogError($"Could not get serial number for tracker at index {index}");
            }
            else
            {
                var t = trackers.FirstOrDefault(tracker => (int) tracker.TrackedObject.index == index);
                if (t != null) t.BatteryLevel = batteryLevel;
            }
        }

        private void SetIndexForSerialNumber(int index)
        {
            var error = ETrackedPropertyError.TrackedProp_Success;
            var serialNumberBuilder = new StringBuilder();
            OpenVR.System.GetStringTrackedDeviceProperty((uint) index,
                ETrackedDeviceProperty.Prop_SerialNumber_String, serialNumberBuilder, 64, ref error);

            if (error != ETrackedPropertyError.TrackedProp_Success)
            {
                Debug.LogError($"Could not get serial number for tracker at index {index}");
            }
            else
            {
                var t = trackers.FirstOrDefault(tracker => tracker.Id == serialNumberBuilder.ToString());
                t?.TrackedObject.SetDeviceIndex(index);
            }
        }
    }
}