#nullable enable
using UnityEngine;
using IGP.UnitySDK;
using IGP.UnitySDK.Core;
using System.Collections;

namespace IGP.UnitySDK
{
    /// <summary>
    /// IGP 网络监控工具 - 简单版
    /// 用于实时监控 KCP 和 P2P 连接的统计信息
    /// </summary>
    public class IGPNetworkMonitor : MonoBehaviour
    {
        [Header("配置")]
        [SerializeField] private IGPRuntimeManager? arenaManager;
        [SerializeField] private bool autoUpdate = true;
        [SerializeField] private float updateInterval = 2f;
        
        [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<IGPRuntimeManager>();
            }
            
            if (arenaManager == null)
            {
                Debug.LogError("[IGP Network Monitor] IGPRuntimeManager not found!");
                enabled = false;
                return;
            }
            
            Debug.Log("[IGP Network Monitor] Started. Monitoring connections...");
            
            if (autoUpdate)
            {
                StartCoroutine(MonitorRoutine());
            }
        }
        
        private IEnumerator MonitorRoutine()
        {
            while (true)
            {
                yield return new WaitForSeconds(updateInterval);

                var manager = arenaManager;
                if (manager == null)
                {
                    yield break;
                }
                
                if (!manager.IsKcpConnected)
                {
                    Debug.LogWarning("[IGP Network Monitor] KCP not connected");
                    continue;
                }
                
                var stats = manager.AppRTTStats;
                var transportStats = manager.KcpTransportStats;
                if (stats != null && stats.SampleCount > 0)
                {
                    Debug.Log($"[IGP Network Monitor] AppSamples={stats.SampleCount}, " +
                             $"AppAvg={stats.AvgRTT*1000:F1}ms, " +
                             $"AppMin={stats.MinRTT*1000:F1}ms, " +
                             $"AppMax={stats.MaxRTT*1000:F1}ms, " +
                             $"KcpSrtt={(transportStats.HasSmoothedRtt ? transportStats.SmoothedRttMs.ToString() : "--")}ms, " +
                             $"WaitSnd={(transportStats.IsAvailable ? transportStats.WaitSnd.ToString() : "--")}, " +
                             $"UdpInPerSec={(transportStats.IsAvailable ? transportStats.DatagramsInPerSecond.ToString("F0") : "--")}, " +
                             $"UdpOutPerSec={(transportStats.IsAvailable ? transportStats.DatagramsOutPerSecond.ToString("F0") : "--")}, " +
                             $"UdpIn={(transportStats.IsAvailable ? transportStats.DatagramsIn.ToString() : "--")}, " +
                             $"UdpOut={(transportStats.IsAvailable ? transportStats.DatagramsOut.ToString() : "--")}, " +
                             $"UdpBytesIn={(transportStats.IsAvailable ? transportStats.DatagramBytesIn.ToString() : "--")}, " +
                             $"UdpBytesOut={(transportStats.IsAvailable ? transportStats.DatagramBytesOut.ToString() : "--")}, " +
                             $"Quality={stats.GetQuality()}, " +
                             $"Alive={manager.IsKcpAlive}");
                }
                else
                {
                    Debug.Log("[IGP Network Monitor] Waiting for samples...");
                }
            }
        }
        
        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), 
                         "IGPRuntimeManager: 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.UnitySDK.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)
            {
                Debug.LogError("IGPRuntimeManager not found");
                return;
            }
            
            Debug.Log("=== IGP Network Status ===");
            Debug.Log($"KCP Connected: {arenaManager.IsKcpConnected}");
            Debug.Log($"KCP Alive: {arenaManager.IsKcpAlive}");
            
            var stats = arenaManager.AppRTTStats;
            if (stats != null)
            {
                Debug.Log($"App {stats}");
            }
            else
            {
                Debug.Log("No network stats available");
            }

            var transportStats = arenaManager.KcpTransportStats;
            if (transportStats.IsAvailable)
            {
                Debug.Log($"KCP Transport: srtt={transportStats.SmoothedRttMs}ms rto={transportStats.RtoMs}ms waitSnd={transportStats.WaitSnd} sndQueue={transportStats.SndQueue} sndBuf={transportStats.SndBuf}");
            }
        }
    }
}
