#nullable enable
using IGP.UnitySDK.Models;
using UnityEngine;
using IGP.UnitySDK;
using IGP.Multiplayer.Core;

namespace IGP.Multiplayer
{
    /// <summary>
    /// IGP 网络监控工具 - 简单版
    /// 用于实时监控 KCP 和 P2P 连接的统计信息
    /// </summary>
    public class IGPNetworkMonitor : MonoBehaviour
    {
        private const string LogScope = "network-monitor";

        [Header("配置")]
        [SerializeField] private IGPMultiplayerRuntime? arenaManager;
        
        [Header("显示设置")]
        [SerializeField] private bool showGUI = true;
        [SerializeField] private bool showPeerLatencies = true;
        [SerializeField] private Rect guiPosition = new Rect(10, 10, 330, 180);
        
        private void Start()
        {
            if (arenaManager == null)
            {
                arenaManager = FindAnyObjectByType<IGPMultiplayerRuntime>();
            }
            
            if (arenaManager == null)
            {
                IGPLog.Error(LogScope, "start", "event=runtime-manager-not-found");
                enabled = false;
                return;
            }

            IGPLog.Info(LogScope, "start", "event=started");
            
        }
        
        private void OnGUI()
        {
            if (!showGUI) return;
            
            GUIStyle boxStyle = new GUIStyle(GUI.skin.box);
            boxStyle.fontSize = 12;
            
            GUIStyle labelStyle = new GUIStyle(GUI.skin.label);
            labelStyle.fontSize = 11;
            
            GUI.Box(guiPosition, "", boxStyle);
            
            float y = guiPosition.y + 5;
            float x = guiPosition.x + 10;
            float lineHeight = 20;
            
            // 标题
            GUIStyle titleStyle = new GUIStyle(GUI.skin.label);
            titleStyle.fontSize = 13;
            titleStyle.fontStyle = FontStyle.Bold;
            GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), 
                     "IGP Network Monitor", titleStyle);
            y += lineHeight;
            
            if (arenaManager == null)
            {
                GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), 
                         "IGPMultiplayerRuntime: Not Found", labelStyle);
                return;
            }
            
            // KCP连接状态
            bool kcpConnected = arenaManager.IsKcpConnected;
            GUI.contentColor = kcpConnected ? Color.green : Color.red;
            GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), 
                     $"KCP: {(kcpConnected ? "✓ Connected" : "✗ Disconnected")}", labelStyle);
            GUI.contentColor = Color.white;
            y += lineHeight;
            
            if (!kcpConnected)
            {
                GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), 
                         "Connect to room first", labelStyle);
                return;
            }
            
            var stats = arenaManager.AppRTTStats;
            var transportStats = arenaManager.KcpTransportStats;
            bool hasAppRtt = stats != null && stats.SampleCount > 0;
            if (!hasAppRtt && !transportStats.IsAvailable)
            {
                GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), 
                         "Measuring RTT...", labelStyle);
                return;
            }
            
            // 连接活跃状态
            bool alive = arenaManager.IsKcpAlive;
            GUI.contentColor = alive ? Color.green : Color.red;
            GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), 
                     $"Alive: {(alive ? "Yes" : "No")}", labelStyle);
            GUI.contentColor = Color.white;
            y += lineHeight;
            
            // RTT统计
            if (hasAppRtt)
            {
                GUI.contentColor = stats!.GetQualityColor();
            }
            GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), 
                     hasAppRtt ? $"App Avg: {stats!.AvgRTT*1000:F0}ms ({stats.GetQuality()})" : "App RTT: measuring", labelStyle);
            GUI.contentColor = Color.white;
            y += lineHeight;
            
            GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), 
                     transportStats.HasSmoothedRtt
                         ? $"KCP: srtt {transportStats.SmoothedRttMs}ms | rto {transportStats.RtoMs}ms"
                         : "KCP: srtt --", labelStyle);
            y += lineHeight;
            
            GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), 
                     transportStats.IsAvailable
                         ? $"Queue: wait {transportStats.WaitSnd} | q {transportStats.SndQueue} | buf {transportStats.SndBuf}"
                         : "Queue: --", labelStyle);
            y += lineHeight;

            GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight),
                     transportStats.IsAvailable
                         ? $"UDP: in {transportStats.DatagramsInPerSecond:F0}/s | out {transportStats.DatagramsOutPerSecond:F0}/s"
                         : "UDP: --", labelStyle);
            y += lineHeight;

            GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight),
                     transportStats.IsAvailable
                         ? $"UDP pkts: in {IGPRTTDisplayFormatting.FormatUdpDatagramCount(transportStats.DatagramsIn)} | out {IGPRTTDisplayFormatting.FormatUdpDatagramCount(transportStats.DatagramsOut)}"
                         : "UDP pkts: --", labelStyle);
            y += lineHeight;

            GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight),
                     transportStats.IsAvailable
                         ? $"UDP bytes: in {IGPRTTDisplayFormatting.FormatByteCount(transportStats.DatagramBytesIn)} | out {IGPRTTDisplayFormatting.FormatByteCount(transportStats.DatagramBytesOut)}"
                         : "UDP bytes: --", labelStyle);
            y += lineHeight;
    
            // 其他玩家 P2P 延迟
            if (showPeerLatencies && arenaManager.Network != null)
            {
                var peerIds = arenaManager.Network.GetConnectedPeerIds();
                if (peerIds.Count > 0)
                {
                    y += 5;
                    GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), 
                             "--- P2P Peer Latencies ---", labelStyle);
                    y += lineHeight;
    
                    foreach (var peerId in peerIds)
                    {
                        uint latency = arenaManager.Network.GetPeerLatency(new IGP.Multiplayer.Network.IGPPlayerID(peerId));
                        GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), 
                                 $"Player {peerId.Substring(Mathf.Max(0, peerId.Length - 6))}: {latency}ms", labelStyle);
                        y += lineHeight;
                    }
                }
            }
    
            // 动态调整高度
            if (y - guiPosition.y > guiPosition.height)
            {
                guiPosition.height = y - guiPosition.y + 5;
            }
        }
        
        /// <summary>
        /// 手动触发一次状态输出
        /// </summary>
        [ContextMenu("Print Status")]
        public void PrintStatus()
        {
            if (arenaManager == null)
            {
                IGPLog.Error(LogScope, "print-status", "event=runtime-manager-not-found");
                return;
            }

            if (!IGPLog.ShouldLog(IGPLogLevel.Info))
            {
                return;
            }

            IGPLog.Info(LogScope, "print-status", "event=status-begin");
            IGPLog.Info(LogScope, "print-status", $"kcpConnected={arenaManager.IsKcpConnected}");
            IGPLog.Info(LogScope, "print-status", $"kcpAlive={arenaManager.IsKcpAlive}");
            
            var stats = arenaManager.AppRTTStats;
            if (stats != null)
            {
                IGPLog.Info(LogScope, "print-status", $"appStats={stats}");
            }
            else
            {
                IGPLog.Info(LogScope, "print-status", "appStats=unavailable");
            }

            var transportStats = arenaManager.KcpTransportStats;
            if (transportStats.IsAvailable)
            {
                IGPLog.Info(
                    LogScope,
                    "print-status",
                    $"kcpSrttMs={transportStats.SmoothedRttMs} kcpRtoMs={transportStats.RtoMs} " +
                    $"waitSnd={transportStats.WaitSnd} sndQueue={transportStats.SndQueue} sndBuf={transportStats.SndBuf}");
            }
        }
    }
}
