using IFramework.Custom;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using Unity.Netcode;
using Unity.Netcode.Transports.UTP;
using UnityEngine;

namespace Rokid.MRC
{
    public enum HostType
    {
        Client,
        Host,
    }

    public enum CastType
    {
        BroadCast,
        MultiCast,
    }

    public class NetworkMgr : UnitySingleton<NetworkMgr>
    {
        public bool NeedBroadCast;

        public HostType hostType;

        public UDPServer udpServer;

        public CastType CastType;

        //连接管理
        private int MaxConnectedClients = 1;
        public int ReconnectAttempts = 2;

        public override void Awake()
        {
            base.Awake();
        }

        private void Start()
        {
            Init();
        }

        public void Init()
        {
            //Debug.Log(IPAddress.Broadcast.ToString());
            //Debug.Log(IPAddress.Any.ToString());
            //Debug.Log("OutSide IP : " + MRCUtility.GetOutSideIP());

            InitConnection();

            InitNetEventHandle();

            if(hostType == HostType.Host)
            {
                if(NeedBroadCast)
                {
                    udpServer = new UDPServer();
                    udpServer.Init(CastType == CastType.BroadCast);
                }
                else
                {
                    gameObject.AddComponent<UDPClientProvider>();
                }

                ConnectionManager.Instance.ConnectionMethod.SetConnectionData("HostIP", "Host", false, false);
                ConnectionManager.Instance.StartHostIp("0.0.0.0", 7777);
            }
        }

        private void InitConnection()
        {
            ConnectionManager.Instance.SetNetworkManager(NetworkManager.Singleton);
            ConnectionManager.Instance.MaxConnectedPlayers = MaxConnectedClients;
            ConnectionManager.Instance.ReconnectAttempts = ReconnectAttempts;
            ConnectionManager.Instance.Init();
        }

        private void InitNetEventHandle()
        {
            MessageCenter.AddMsgListener(EventDefine.ServerConnectionEvent, ConnectionEventHandle);
            MessageCenter.AddMsgListener(EventDefine.ConnectStatusEvent, ConnectStatusEventHandle);
            MessageCenter.AddMsgListener(EventDefine.ClientDisConnectionEvent, DisConnectionEventHandle);
            MessageCenter.AddMsgListener(EventDefine.ClientReConnectionEvent, ReConnectionEventHandle);
        }

        //服务端
        private void ConnectionEventHandle(object val)
        {
            ConnectionEventMessage msg = (ConnectionEventMessage)val;
            //Debug.Log($"ConnectionEventHandle : ConnectStatus —— {msg.ConnectStatus} PlayerName —— {msg.PlayerName}");

            if(msg.ConnectStatus == ConnectStatus.GenericDisconnect)
            {
                //某个客户端断开
                UIManager.Instance.ShowTips(string.Format(LocalizationMgr.Instance.GetTextByKey("TipsConnected"), msg.PlayerName));

                //隐藏校准提示界面（todo，目前先用弹窗界面）
                UIManager.Instance.ClosePanel(UIType.Confirm);

                //隐藏合成相机
                ResourceManager.Instance.ShowRenderCamera(false);
                TransmissionClient.Release();
            }
        }

        //通用
        private void ConnectStatusEventHandle(object val)
        {
            ConnectStatus status = (ConnectStatus)val;
            //Debug.Log($"ConnectStatusEventHandle : ConnectStatus —— {status}");

            //Host启动失败
            if(status == ConnectStatus.StartHostFailed)
            {
                UIManager.Instance.ShowTips(LocalizationMgr.Instance.GetTextByKey("TipsConnected"));
            }

            //Host启动成功
            if(status == ConnectStatus.Success)
            {

            }
        }

        //客户端
        private void DisConnectionEventHandle(object val)
        {
            ConnectStatus reason = (ConnectStatus)val;

            Debug.Log($"DisConnectionEventHandle : Reason —— {reason}");
        }

        //客户端
        private void ReConnectionEventHandle(object val)
        {
            ReconnectMessage msg = (ReconnectMessage)val;
            Debug.Log($"ReConnectionEventHandle : CurrentAttempt —— {msg.CurrentAttempt} MaxAttempt —— {msg.MaxAttempt}");
        }

        //作为客户端启动
        public void StartNetCodeClient(string ip)
        {
            ConnectionManager.Instance.ChangeState(ConnectionManager.Instance.m_Offline);
            ConnectionManager.Instance.StartClientIp(ip, 7777);
        }

        public void OnDestroy()
        {
            udpServer?.OnDestroy();
        }

        private void OnApplicationQuit()
        {
            //Debug.LogError("NetworkMgr OnApplicationQuit");
            NetworkManager.Singleton?.Shutdown();
        }
    }
}