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

namespace _PROJECT.Multiplayer.NewBow
{
    public class TwoHandedBowNotch : XRSocketInteractor
    {
        [SerializeField, Range(0, 1)] private float releaseThreshold = 0.25f;
        
        public AudioClipGroup nockSounds;
        public AudioClipGroup releaseSounds;
        
        private TwoHandedBow _bow;
        private TwoHandedBowNetworkManager _networkBehavior;

        protected override void Awake()
        {
            base.Awake();
            _bow = GetComponentInParent<TwoHandedBow>();
            _networkBehavior = GetComponentInParent<TwoHandedBowNetworkManager>();
        }   
        
        protected override void OnEnable()
        {
            base.OnEnable();
            _bow.selectExited.AddListener(ReleaseArrow);
        }

        protected override void OnDisable()
        {
            base.OnDisable();
            _bow.selectExited.RemoveListener(ReleaseArrow);
        }
        
        public void ReleaseArrow(SelectExitEventArgs args)
        {
            Debug.Log("Notch select exit by " + args.interactorObject);
            Debug.Log("Notch has selection: " + hasSelection);
            if (!hasSelection) return;
            // Pulled enough to release the arrow
            Debug.Log("Notch pull amount: " + _bow.PullAmount);
            if (_bow.PullAmount < releaseThreshold) return;
            // Bow is still being held by the other hand,
            Debug.Log("Notch other hand is selecting: " + _bow.firstInteractorSelecting);
            if (_bow.firstInteractorSelecting == null) return;
            Debug.Log("Notch other hand is not selecting");
            Debug.Log("Sending Arrow Release RPC");
            _networkBehavior.LaunchArrow(_bow.PullAmount);
        }
        
        public override bool CanSelect(IXRSelectInteractable interactable)
        {
            return QuickSelect(interactable) && CanHover(interactable) && interactable is Arrow;
        }

        public override void ProcessInteractor(XRInteractionUpdateOrder.UpdatePhase updatePhase)
        {
            base.ProcessInteractor(updatePhase);

            // Move attach when bow is pulled, this updates the renderer as well
            attachTransform.position = _bow.secondaryAttachTransform.position;
        }

        private bool QuickSelect(IXRSelectInteractable interactable)
        {
            // This lets the Notch automatically grab the arrow
            return !hasSelection || IsSelecting(interactable);
        }

        private bool CanHover(IXRSelectInteractable interactable)
        {
            if (interactable is IXRHoverInteractable hoverInteractable)
                return CanHover(hoverInteractable);

            return false;
        }

        public Vector3 GetLaunchDirection()
        {
            return _networkBehavior.lastKnownLaunchDirection;
        }

        public void SetLaunchDirection(Vector3 direction)
        {
            Debug.Log("Setting launch direction: " + direction);
            if (direction != Vector3.zero)
            {
                _networkBehavior.SetLaunchDirection(direction);
                return;
            }
            Debug.Log("Launch direction is zero");
        }
        
        public void PlayNockSound()
        {
            nockSounds.Play();
        }
        
        public void PlayReleaseSound()
        {
            releaseSounds.Play();
        }

        public float GetLastKnownPullAmount()
        {
            return _networkBehavior.lastKnownPullAmount;
        }
    }
}