using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Netcode;
using UnityEngine;


namespace Rokid.MRC
{
    //空间坐标系数据
    public struct SpacePose : INetworkSerializable, IEquatable<SpacePose>
    {
        public ulong ClientId;
        public Vector3 Position;
        public Quaternion Rotaion;
        public ARCalibrationMode CalibrationMode;

        public SpacePose(ulong clientId, Vector3 pos, Quaternion rot, ARCalibrationMode calibrationMode)
        {
            ClientId = clientId;
            Position = pos;
            Rotaion = rot;

            CalibrationMode = calibrationMode;
        }

        public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
        {
            serializer.SerializeValue(ref ClientId);
            serializer.SerializeValue(ref Position);
            serializer.SerializeValue(ref Rotaion);
            serializer.SerializeValue(ref CalibrationMode);
        }

        public bool Equals(SpacePose other)
        {
            return ClientId == other.ClientId &&
                   Position.Equals(other.Position) &&
                   Rotaion.Equals(other.Rotaion) &&
                   CalibrationMode == other.CalibrationMode;
        }
    }

    //空间坐标系同步
    public class SpaceCoordinateBehavior : NetworkBehaviorBase
    {
        //所有客户端的空间坐标系
        public NetworkList<SpacePose> ClientSpacePoseList;
        //所有服务端的空间坐标系
        public NetworkList<SpacePose> ServerSpacePoseList;

        private void Awake()
        {
            ClientSpacePoseList = new NetworkList<SpacePose>();

            ServerSpacePoseList = new NetworkList<SpacePose>();
        }

        ////服务端RPC调用其他客户端的方法
        //[ClientRpc]
        //public void InstantiateSyncObjectClientRpc()
        //{
        //    //Host模式，服务端也会调用该方法，此时IsClient、IsServer、IsHost三个值都为true，只有IsConnectedClient是false
        //    if(NetworkManager.Singleton.IsConnectedClient && NetworkMgr.Instance.syncLogoPrefab)
        //    {
        //        NetworkObject networkObject = Instantiate(NetworkMgr.Instance.syncLogoPrefab).GetComponent<NetworkObject>();
        //        if(networkObject)
        //        {
        //            Debug.Log("Client InstantiateSyncObjectClientRpc");
        //        }
        //    }
        //}

        //客户端调用。客户端通知正在开启脸部追踪，服务端可以不做任何处理
        [ServerRpc(RequireOwnership = false)]
        public void ReqStartBuildServerRpc(ulong clientID, ARCalibrationMode calibrationMode)
        {
            ServerSpaceCoordController.Instance.ClientStartBuild(clientID, calibrationMode);
        }

        //客户端调用。客户端取消校准
        [ServerRpc(RequireOwnership = false)]
        public void ReqCancelBuildServerRpc(ulong clientID)
        {
            ServerSpaceCoordController.Instance.ClientCancelBuild();
        }

        //客户端调用。客户端通知构建完成，服务端更新数据，并返回客户端
        //原本ServerRpc只能Owner调用，但是加了RequireOwnership = false以后，每个客户端都可以调用
        [ServerRpc(RequireOwnership = false)]
        public void ChangeSpaceCoordServerRpc(ulong clientId, SpacePose spacePose)
        {
            ServerSpaceCoordController.Instance.ClientConfirmSpacePose(clientId, spacePose);
        }

        //更新所有客户端的坐标系
        public void UpdateClientSpacePose(ulong clientId, SpacePose spacePose)
        {
            //服务端更新该SpacePose
            for(int i = 0;i < ClientSpacePoseList.Count;i++)
            {
                if(ClientSpacePoseList[i].ClientId == spacePose.ClientId)
                {
                    ClientSpacePoseList[i] = spacePose;
                    return;
                }
            }

            //服务端添加该SpacePose
            ClientSpacePoseList.Add(spacePose);
        }

        //更新所有服务端坐标系
        public void UpdateServerSpacePose(ulong clientId, SpacePose spacePose)
        {
            for(int i = 0;i < ServerSpacePoseList.Count;i++)
            {
                if(ServerSpacePoseList[i].ClientId == spacePose.ClientId)
                {
                    ServerSpacePoseList[i] = spacePose;
                    return;
                }
            }

            ServerSpacePoseList.Add(spacePose);
        }

        public SpacePose GetServerSpacePose(ulong clientId)
        {
            for(int i = 0;i < ServerSpacePoseList.Count;i++)
            {
                if(ServerSpacePoseList[i].ClientId == clientId)
                {
                    return ServerSpacePoseList[i];
                }
            }

            return default(SpacePose);
        }

    }
}
