using FishNet.Object;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;

namespace _PROJECT.Multiplayer
{
    public class XRMultiplayerInteractionManager : XRInteractionManager
    {
        private XRMultiplayerInteractionManagerBehavior _networkBehavior;
        
        private new void Awake()
        {
            base.Awake();
            _networkBehavior = GetComponentInChildren<XRMultiplayerInteractionManagerBehavior>();
        }
        
        public override void SelectEnter(IXRSelectInteractor interactor, IXRSelectInteractable interactable)
        {
            Debug.Log(interactor);
            Debug.Log(interactable);
            Debug.Log("SelectEnter called on " + interactable.transform.name + " by " + interactor.transform.name);
            NetworkObject nInteractable = GetNetworkObject(interactable);
            if (nInteractable == null)
            {
                // Interactable is not a network object, so we can just select it.
                base.SelectEnter(interactor, interactable);
                return;
            }
            
            NetworkObject nInteractor = GetNetworkObject(interactor);
            if (nInteractor == null)
            {
                // Interactable is a network object, but interactor is not.
                base.SelectEnter(interactor, interactable);
                return;
            }
            
            // Both interactable and interactor are network objects, so we should broadcast selectEnter to all clients.
            _networkBehavior.RequestSelectEnterBroadcastRPC(nInteractor, nInteractable);
        }

        public override void SelectExit(IXRSelectInteractor interactor, IXRSelectInteractable interactable)
        {
            Debug.Log("SelectExit called on " + interactable.transform.name + " by " + interactor.transform.name);
            NetworkObject nInteractable = GetNetworkObject(interactable);
            if (nInteractable == null)
            {
                // Interactable is not a network object, so we can just unselect it.
                base.SelectExit(interactor, interactable);
                return;
            }
            
            NetworkObject nInteractor = GetNetworkObject(interactor);
            if (nInteractor == null)
            {
                // Interactable is a network object, but interactor is not.
                base.SelectExit(interactor, interactable);
                return;
            }
            
            // Both interactable and interactor are network objects, so we should broadcast selectExit to all clients.
            _networkBehavior.RequestSelectExitBroadcastRPC(nInteractor, nInteractable);
        }
        
        private static NetworkObject GetNetworkObject(IXRInteractable interactable)
        {
            return interactable.transform.GetComponent<NetworkObject>();
        }

        private static NetworkObject GetNetworkObject(IXRInteractor interactor)
        {
            return interactor.transform.GetComponent<NetworkObject>();
        }

        public void BaseSelectEnter(IXRSelectInteractor iInteractor, IXRSelectInteractable iInteractable)
        {
            base.SelectEnter(iInteractor, iInteractable);
        }

        public void BaseSelectExit(IXRSelectInteractor iInteractor, IXRSelectInteractable iInteractable)
        {
            base.SelectExit(iInteractor, iInteractable);
        }
    }
}