using Rokid.MRC;
using System;
using System.Collections;
using Unity.Multiplayer.Samples.Utilities;
using Unity.Netcode;
using UnityEngine;

//Host模式的稳定状态。服务端开启成功后，最终在这个状态
class HostingState : OnlineState
{
    //客户端登录信息最大尺寸
    const int MaxConnectPayload = 1024;

    public override void Enter()
    {
        //Todo，服务端切换场景
    }

    public override void Exit()
    {
        //玩家信息管理，将所有玩家踢下线
        PlayerManager.Instance.OnServerEnded();
    }

    //某个客户端连接到服务端，但是还没通过登录验证
    public override void OnClientConnected(ulong clientId)
    {
        //触发消息，此时的客户端数据，可能是之前遗留的。Todo，在ApprovalCheck中触发
        //MessageCenter.SendMessage(EventDefine.ServerConnectionEvent, new ConnectionEventMessage() { ConnectStatus = ConnectStatus.Success, PlayerName = ServerSessionManager<SessionPlayerData>.Instance.GetPlayerData(clientId)?.PlayerName });
    }

    //客户端断开连接
    public override void OnClientDisconnect(ulong clientId)
    {
        if(clientId == m_ConnectionManager.NetworkManager.LocalClientId)
        {
            //服务端自己关闭
            m_ConnectionManager.ChangeState(m_ConnectionManager.m_Offline);
        }
        else
        {
            //其他客户端断开连接。移除该客户端数据
            string playerId = PlayerManager.Instance.GetPlayerId(clientId);
            if(playerId != null)
            {
                //设置玩家断线
                PlayerManager.Instance.DisconnectClient(clientId);

                //有该玩家数据，则触发
                MessageCenter.SendMessage(EventDefine.ServerConnectionEvent, new ConnectionEventMessage() { ConnectStatus = ConnectStatus.GenericDisconnect, PlayerName = PlayerManager.Instance.GetPlayerData(playerId)?.PlayerName });
            }
        }
    }

    //服务端主动关闭
    public override void OnUserRequestedShutdown()
    {
        //给所有客户端发消息
        m_ConnectionManager.SendServerToAllClientsSetDisconnectReason(ConnectStatus.HostEndedSession);

        //关闭服务端
        m_ConnectionManager.NetworkManager.StartCoroutine(WaitToShutdown());
    }

    //处理其他客户端登录请求
    public override void ApprovalCheck(NetworkManager.ConnectionApprovalRequest request, NetworkManager.ConnectionApprovalResponse response)
    {
        //客户端数据（Json格式），包括玩家名称、Guid等信息
        var connectionData = request.Payload;
        var clientId = request.ClientNetworkId;

        if(connectionData.Length > MaxConnectPayload)
        {
            //数据超标
            response.Approved = false;
            return;
        }

        //解析数据
        string payload = System.Text.Encoding.UTF8.GetString(connectionData);
        ConnectionPayload connectionPayload = JsonUtility.FromJson<ConnectionPayload>(payload);

        //连接状态
        ConnectStatus gameReturnStatus = GetConnectStatus(connectionPayload);

        if(gameReturnStatus == ConnectStatus.Success)
        {
            //连接成功

            //保存客户端登录信息
            PlayerData playerData = new PlayerData(clientId, connectionPayload, true);
            PlayerManager.Instance.SetupConnectingPlayerSessionData(clientId, connectionPayload.playerId , playerData);

            //延迟生成锚点，因为客户端此时还未收到连接成功信息，如果服务端在此时就生成Anchor，客户端不会同步生成
            //NetworkObject必须由服务端生成，客户端没有权限
            if(connectionPayload.needAnchor)
            {
                m_ConnectionManager.NetworkManager.StartCoroutine(WaitForClientConnected(playerData, connectionPayload.needAnchor));
            }

            //触发消息
            MessageCenter.SendMessage(EventDefine.ServerConnectionEvent, new ConnectionEventMessage() { ConnectStatus = ConnectStatus.Success, PlayerName = PlayerManager.Instance.GetPlayerData(clientId)?.PlayerName });

            response.Approved = true;
            response.CreatePlayerObject = false;
            response.Position = Vector3.zero;
            response.Rotation = Quaternion.identity;

            return;
        }

        IEnumerator WaitToDenyApproval()
        {
            response.Pending = true;
            response.Approved = false;

            m_ConnectionManager.SendServerToClientSetDisconnectReason(clientId, gameReturnStatus);

            yield return null;

            response.Pending = false;
        }

        //连接失败，则告诉客户端原因
        m_ConnectionManager.SendServerToClientSetDisconnectReason(clientId, gameReturnStatus);

        m_ConnectionManager.NetworkManager.StartCoroutine(WaitToDenyApproval());
    }

    IEnumerator WaitForClientConnected(PlayerData playerData, bool showAnchor)
    {
        yield return new WaitUntil(() =>
        {
            if(m_ConnectionManager.NetworkManager.ConnectedClients.ContainsKey(playerData.ClientId))
            {
                return true;
            }
            return false;
        });
        
        //生成Anchor模型
        playerData.Anchor = ResourceManager.Instance.CreateClientAnchor(playerData);
        playerData.Anchor.SetActive(showAnchor);

        MessageCenter.SendMessage(GlobalDefine.ClientAnchorInstantiate, null);
    }

    //返回连接状态
    ConnectStatus GetConnectStatus(ConnectionPayload connectionPayload)
    {
        if(m_ConnectionManager.NetworkManager.ConnectedClientsIds.Count > m_ConnectionManager.MaxConnectedPlayers)
        {
            return ConnectStatus.ServerFull;
        }

        //该客户端是Debug版本，不允许
        //if(connectionPayload.isDebug != Debug.isDebugBuild)
        //{
        //    return ConnectStatus.IncompatibleBuildType;
        //}

        //判断是否视频流
        if(connectionPayload.isVideo && PlayerManager.Instance.HaveVideoPlayer())
        {
            return ConnectStatus.AlreadyHaveVideoClient;
        }

        //是否已经有该玩家
        if(PlayerManager.Instance.IsDuplicateConnection(connectionPayload.playerId))
        {
            //已经有该客户端，重复登录
            return ConnectStatus.LoggedInAgain;
        }
        else
        {
            return ConnectStatus.Success;
        }
    }

    //切换到OfflineState状态
    IEnumerator WaitToShutdown()
    {
        yield return null;
        m_ConnectionManager.ChangeState(m_ConnectionManager.m_Offline);
    }

}