using UnityEngine;
using Mirror;
using Mirror.Experimental;
using NetworkTransform = Mirror.NetworkTransform;

public class PropGrab : NetworkBehaviour, IInteractable
{
    [SyncVar(hook = nameof(OnPlayerChanged))]
    public NetworkIdentity _player;

    private Rigidbody _rb;
    private GameObject _eyesObject;

    private NetworkTransform _netTransform;
    private NetworkRigidbody _netRigidBody;

    void Start()
    {
        _rb = GetComponent<Rigidbody>();
        _netTransform = GetComponent<NetworkTransform>();
        _netRigidBody = GetComponent<NetworkRigidbody>();
    }

    void Update()
    {
        if (!hasAuthority || _player == null || _eyesObject == null) return;

        if (_player.isLocalPlayer)
        {
            Vector3 targetPos = _eyesObject.transform.position + _eyesObject.transform.forward;
            Vector3 tarForce = targetPos - _rb.transform.position;
            Vector3 force = (tarForce * 20f - _rb.velocity) * Time.deltaTime * 40f;

            _rb.AddForce(force, ForceMode.Impulse);

            CmdAddForce(force);
        }



        // _rb.MoveRotation(_eyesObject.transform.rotation);
        // _rb.transform.rotation = _eyesObject.transform.rotation;

        // transform.position = Vector3.Lerp(transform.position, targetPos, 0.95f);
    }

    [Command(requiresAuthority = false)]
    void CmdAddForce(Vector3 force)
    {
        _rb.AddForce(force, ForceMode.Impulse);
    }

    // [ClientRpc]
    // void RpcAddForce(Vector3 force)
    // {
    //     _rb.AddForce(force, ForceMode.Impulse);
    // }

    public void Interact()
    {
        CmdInteract();
    }

    [Command(requiresAuthority = false)]
    private void CmdInteract(NetworkConnectionToClient sender = null)
    {
        var currentClient = netIdentity.connectionToClient;

        if (currentClient != null && currentClient.identity.netId == sender.identity.netId)
        {
            ResetPlayer();

            return;
        }
        else if (currentClient != null) return;

        netIdentity.AssignClientAuthority(sender);
        _player = sender.identity;
    }

    private void OnPlayerChanged(NetworkIdentity oldPlayer, NetworkIdentity newPlayer)
    {
        _netTransform.clientAuthority = newPlayer != null;
        _netRigidBody.clientAuthority = newPlayer != null;

        if (newPlayer != null)
        {
            Grab(newPlayer);
        }
        else
        {
            Drop(oldPlayer);
        }
    }

    [Server]
    public void ResetPlayer()
    {
        netIdentity.RemoveClientAuthority();
        _player = null;
    }

    private void Grab(NetworkIdentity player)
    {
        player.gameObject.GetComponent<Interactions>().SetGrabbedProp(this);
        _eyesObject = _player.gameObject.GetComponent<Interactions>()._eyesObject;
        gameObject.layer = LayerMask.NameToLayer("Grab");
    }

    void Drop(NetworkIdentity player)
    {
        player.gameObject.GetComponent<Interactions>().SetGrabbedProp(null);
        // netIdentity.RemoveClientAuthority();
        _player = null;
        _eyesObject = null;
        gameObject.layer = LayerMask.NameToLayer("Default");
    }
}