using System;
using Obvious.Soap;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.InputSystem;

namespace Conjure.Input
{
    public class GameJoiner : SerializedMonoBehaviour
    {
        [Required, SerializeField]
        private ScriptableEventInt onJoinEvent;
        [Required, SerializeField]
        private ScriptableEventInt onLeaveEvent;

        [SerializeField, Required]
        private InputServerReference inputManagerGameobjectReference;

        private InputManagerServer _inputManagerServer;

        private void Awake()
        {
            if (inputManagerGameobjectReference.Value is not null)
            {
                _inputManagerServer = inputManagerGameobjectReference.Value.GetComponent<InputManagerServer>();
            }

            if (_inputManagerServer is null)
            {
                throw new NullReferenceException(
                    $"The gameobject referenced by {inputManagerGameobjectReference.name} should have a InputManagerServer Component attached");
            }
        }
    
        public void Join(InputAction.CallbackContext context)
        {
            InputDevice device = context.control.device;
            
            // CHECK IF MAPPED TO A PLAYER
            if (_inputManagerServer.GetPlayerFromDeviceId(device.deviceId) != PlayerEnum.None)
            {
                return;
            }

            // TRY TO REGISTER IF THERE'S A SLOT FREE
            PlayerEnum player = _inputManagerServer.RegisterDevice(device.deviceId);
            if (player == PlayerEnum.None)
            {
                return;
            }

            
            onJoinEvent.Raise((int)player);
        }

        public void Leave(InputAction.CallbackContext context)
        {
            InputDevice device = context.control.device;
            PlayerEnum player = _inputManagerServer.GetPlayerFromDeviceId(device.deviceId);

            if (player == PlayerEnum.None)
            {
                return;
            }
            _inputManagerServer.UnregisterDevice(device.deviceId);
        
            onLeaveEvent.Raise((int)player);
        }
    }
}
