using Unity.Netcode;
using UnityEngine;

public delegate Vector3 PositionFunc(Vector3 pos);
public delegate Quaternion RotationFunc(Quaternion pos);

public class NetCodeTransform : NetworkBehaviour
{
    NetworkVariable<Vector3> syncPostion;
    NetworkVariable<Quaternion> syncRotation;
    NetworkVariable<Vector3> syncScale;

    public float deltaTime;
    private float endTime;

    public float interpolationTime = 0.1f;

    private PositionFunc posHandler;
    private RotationFunc rotHandler;

    void Awake()
    {
        syncPostion = new NetworkVariable<Vector3>();
        syncRotation = new NetworkVariable<Quaternion>();
        syncScale = new NetworkVariable<Vector3>();
    }

    void Update()
    {
        ServerSync();
    }

    public override void OnNetworkSpawn()
    {
        base.OnNetworkSpawn();

        //if(NetworkManager.Singleton.IsConnectedClient)
        //{
        //    syncPostion.OnValueChanged += OnPosValueChange;
        //    syncScale.OnValueChanged += OnScaleValueChange;
        //    syncRotation.OnValueChanged += OnRotationValueChange;
        //}
    }

    public override void OnNetworkDespawn()
    {
        base.OnNetworkDespawn();

        //if(NetworkManager.Singleton.IsConnectedClient)
        //{
        //    syncPostion.OnValueChanged -= OnPosValueChange;
        //    syncScale.OnValueChanged -= OnScaleValueChange;
        //    syncRotation.OnValueChanged -= OnRotationValueChange;
        //}
    }

    private void ServerSync()
    {
        if(IsServer)
        {
            if(CheckDeltaTime())
            {
                //服务端
                syncPostion.Value = transform.position;
                syncRotation.Value = transform.rotation;
                syncScale.Value = transform.localScale;
            }
        }
        else if(NetworkManager.Singleton.IsConnectedClient)
        {
            if(posHandler != null && rotHandler != null)
            {
                //客户端
                transform.position = Vector3.Lerp(transform.position, posHandler(syncPostion.Value), interpolationTime);
                transform.localScale = Vector3.Lerp(transform.localScale, syncScale.Value, interpolationTime);
                transform.rotation = Quaternion.Slerp(transform.rotation, rotHandler(syncRotation.Value), interpolationTime);
            }
        }
    }

    bool CheckDeltaTime()
    {
        if(Time.time >= endTime)
        {
            endTime = Time.time + deltaTime;

            return true;
        }

        return false;
    }

    private void OnPosValueChange(Vector3 oldPos, Vector3 newPos)
    {
        if(NetworkManager.Singleton.IsConnectedClient)
        {
            //客户端
            transform.position = Vector3.Lerp(transform.position, newPos, interpolationTime);
            //transform.position = Vector3.SmoothDamp(transform.position, newPos, ref curVelocity, interpolationTime);
        }
    }

    private Vector3 curVelocity;
    private void OnScaleValueChange(Vector3 oldScale, Vector3 newScale)
    {
        if(NetworkManager.Singleton.IsConnectedClient)
        {
            //客户端
            transform.localScale = Vector3.Lerp(transform.localScale, newScale, interpolationTime);
            //transform.localScale = Vector3.SmoothDamp(transform.localScale, newScale, ref curVelocity,interpolationTime);
        }
    }

    private void OnRotationValueChange(Quaternion oldRot, Quaternion newRot)
    {
        if(NetworkManager.Singleton.IsConnectedClient)
        {
            //客户端
            transform.rotation = Quaternion.Slerp(transform.rotation, newRot, interpolationTime);
        }
    }
}
