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

namespace Rokid.MRC
{
    public class ClientRequest : INetworkSerializable
    {
        public enum OpType
        {
            StartBuild,
            CancelBuild,
            ChangeCoord,
            ChangeScreenOrit,
        }

        public ulong ClientId;

        public ARCalibrationMode CalibrationMode;

        public OpType op;

        public SpacePose Pose;

        public bool isPortrait;

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

    public class ServerRequest : INetworkSerializable
    {
        public enum OpType
        {
            ChangeCoord,
            StartStream,
        }

        public OpType op;

        public SpacePose Pose;

        public string msg;

        public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
        {
            serializer.SerializeValue(ref op);
            serializer.SerializeValue(ref Pose);
            serializer.SerializeValue(ref msg);
        }
    }

    public class ServerMessageDispatcher : Singleton<ServerMessageDispatcher>
    {
        public ScreenOrientation clientScreenOrientation;

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

            //NetworkManager.Singleton.CustomMessagingManager.RegisterNamedMessageHandler(nameof(StartBuild), StartBuild);

            if(NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
            {
                NetworkManager.Singleton.CustomMessagingManager.OnUnnamedMessage += OnReceivedMessage;
            }
        }

        //所有客户端的空间坐标系
        public List<SpacePose> ClientSpacePoseList = new List<SpacePose>();
        //所有服务端的空间坐标系
        public List<SpacePose> ServerSpacePoseList = new List<SpacePose>();

        //更新所有客户端的坐标系
        public void UpdateClientSpaceCoord(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 UpdateServerSpaceCoord(ulong clientId, SpacePose serverSpacePose)
        {
            bool isUpdate = false;
            for(int i = 0;i < ServerSpacePoseList.Count;i++)
            {
                if(ServerSpacePoseList[i].ClientId == serverSpacePose.ClientId)
                {
                    ServerSpacePoseList[i] = serverSpacePose;
                    isUpdate = true;
                }
            }

            if(!isUpdate)
            {
                ServerSpacePoseList.Add(serverSpacePose);
            }

            //发包给手机端
            SyncServerPoseToClient(clientId, serverSpacePose);
        }

        //眼镜端同步位姿到手机端
        private void SyncServerPoseToClient(ulong clientId, SpacePose pose)
        {
            FastBufferWriter writer = new FastBufferWriter(1100, Allocator.Temp);
            using(writer)
            {
                ServerRequest serverReq = new ServerRequest();
                serverReq.op = ServerRequest.OpType.ChangeCoord;
                serverReq.Pose = pose;

                serverReq.msg = MRCUtility.GetWirelessIP(AddressType.IPv4);
                //写入消息体
                writer.WriteValueSafe(serverReq);
                //NetworkManager.Singleton.CustomMessagingManager.SendUnnamedMessage(clientId, writer, NetworkDelivery.ReliableFragmentedSequenced);
                NetworkManager.Singleton.CustomMessagingManager.SendUnnamedMessage(clientId, writer);
            }
        }

        public void SyncStartStream(ulong clientId)
        {
            FastBufferWriter writer = new FastBufferWriter(1100, Allocator.Temp);
            using(writer)
            {
                ServerRequest serverReq = new ServerRequest();
                serverReq.op = ServerRequest.OpType.StartStream;
                serverReq.msg = MRCUtility.GetWirelessIP(AddressType.IPv4);
                //写入消息体
                writer.WriteValueSafe(serverReq);
                NetworkManager.Singleton.CustomMessagingManager.SendUnnamedMessage(clientId, writer);
            }
        }

        private void OnReceivedMessage(ulong clientId, FastBufferReader reader)
        {
            //服务端收到数据
            reader.ReadValueSafe<ClientRequest>(out ClientRequest clientReq);

            if(clientReq.op == ClientRequest.OpType.StartBuild)
            {
                if(clientReq.CalibrationMode == ARCalibrationMode.FaceTrack)
                {
                    //TODO，暂时先用Confirm界面来提示
                    UIManager.Instance.ShowConfirm(
                        LocalizationMgr.Instance.GetTextByKey("BuildTitle"),
                        string.Format(LocalizationMgr.Instance.GetTextByKey("BuildReq"), PlayerManager.Instance.GetPlayerData(clientReq.ClientId)?.PlayerName),
                        ConfirmType.None);
                }
                else if(clientReq.CalibrationMode == ARCalibrationMode.SelfCalibration)
                {
                    //自构建，创建手机模型
                    ResourceManager.Instance.CreatePhoneAnchor();

                    MRCDriver.Instance.SelfCalibrationPhone.gameObject.SetActive(true);
                }
            }
            else if(clientReq.op == ClientRequest.OpType.CancelBuild)
            {
                UIManager.Instance.ClosePanel(UIType.Confirm);
            }
            else if(clientReq.op == ClientRequest.OpType.ChangeCoord)
            {
                //更新客户端Pose列表
                UpdateClientSpaceCoord(clientId, clientReq.Pose);

                SpacePose serverSpacePose = default(SpacePose);
                if(clientReq.CalibrationMode == ARCalibrationMode.FaceTrack)
                {
                    //更新服务端Pose列表
                    serverSpacePose = new SpacePose(clientId, Camera.main.transform.position, Camera.main.transform.rotation, clientReq.CalibrationMode);
                }
                else if(clientReq.CalibrationMode == ARCalibrationMode.SelfCalibration)
                {
                    serverSpacePose = new SpacePose(clientId, MRCDriver.Instance.SelfCalibrationPhone.position, MRCDriver.Instance.SelfCalibrationPhone.rotation, clientReq.CalibrationMode);

                    MRCDriver.Instance.SelfCalibrationPhone.gameObject.SetActive(false);
                }

                //同步眼镜端位姿
                UpdateServerSpaceCoord(clientId, serverSpacePose);

                //通知构建提示界面关闭
                MessageCenter.SendMessage(GlobalDefine.SpaceBuildEnd, null);

                //CompositionManager.Instance.StartConnectStream();
            }
            else if(clientReq.op == ClientRequest.OpType.ChangeScreenOrit)
            {
                //横竖屏切换

                Debug.Log($"ChangeScreenOrit Is Portrait : {clientReq.isPortrait}");

                CameraController.Instance.ChangeFollowTargetOrientation(clientReq.isPortrait);
            }
        }

    }
}