#nullable enable
using UnityEngine;
using UnityEngine.UI;
using IGP.UnitySDK.Core;

namespace IGP.UnitySDK.UI
{
    /// <summary>
    /// RTT统计显示组件
    /// 支持OnGUI和UGUI两种显示方式
    /// </summary>
    public class IGPRTTDisplay : MonoBehaviour
    {
        [Header("References")]
        [SerializeField] private IGPRuntimeManager? arenaManager = null;
        
        [Header("OnGUI Settings")]
        [Tooltip("是否使用OnGUI显示")]
        [SerializeField] private bool useOnGUI = true;
        
        [Tooltip("OnGUI显示位置")]
        [SerializeField] private Rect guiPosition = new Rect(10, 10, 330, 220);
        
        [Header("UGUI References (Optional)")]
        [Tooltip("显示延迟的Text组件")]
        [SerializeField] private Text? rttText = null;
        
        [Tooltip("显示连接状态的Text组件")]
        [SerializeField] private Text? statusText = null;
        
        [Tooltip("网络质量指示器")]
        [SerializeField] private Image? qualityIndicator = null;
        
        [Tooltip("详细统计面板")]
        [SerializeField] private GameObject? detailsPanel = null;
        
        [Tooltip("详细统计Text")]
        [SerializeField] private Text? detailsText = null;
        
        [Header("Display Settings")]
        [Tooltip("是否显示详细统计")]
        [SerializeField] private bool showDetails = true;

        [Tooltip("是否显示其他玩家的P2P估算延迟")]
        [SerializeField] private bool showPeerLatencies = true;
        
        [Tooltip("更新频率（秒）")]
        [SerializeField] private float updateInterval = 0.1f;
        
        [Header("Colors")]
        [SerializeField] private Color excellentColor = Color.green;
        [SerializeField] private Color goodColor = Color.yellow;
        [SerializeField] private Color fairColor = new Color(1f, 0.5f, 0f); // 橙色
        [SerializeField] private Color poorColor = new Color(1f, 0.3f, 0f); // 深橙
        [SerializeField] private Color badColor = Color.red;
        
        private float lastUpdateTime;
        
        private void Start()
        {
            // 如果没有设置IGPRuntimeManager，尝试查找
            if (arenaManager == null)
            {
                arenaManager = FindAnyObjectByType<IGPRuntimeManager>();
            }
            
            if (arenaManager == null)
            {
                Debug.LogWarning("[IGP RTT Display] IGPRuntimeManager not found");
            }
            
            lastUpdateTime = Time.time;
        }
        
        private void Update()
        {
            // 限制更新频率
            if (Time.time - lastUpdateTime < updateInterval)
            {
                return;
            }
            
            lastUpdateTime = Time.time;
            
            // 更新UGUI
            if (!useOnGUI)
            {
                UpdateUGUI();
            }
        }
        
        private void OnGUI()
        {
            if (!useOnGUI || arenaManager == null)
            {
                return;
            }
            
            // 检查KCP连接
            if (!arenaManager.IsKcpConnected)
            {
                GUI.Box(guiPosition, "IGP Network Monitor");
                GUI.Label(new Rect(guiPosition.x + 10, guiPosition.y + 25, guiPosition.width - 20, 20), 
                    "KCP: 未连接");
                return;
            }
            
            var appStats = arenaManager.AppRTTStats;
            var transportStats = arenaManager.KcpTransportStats;
            bool hasAppRtt = appStats != null && appStats.SampleCount > 0;
            if (!hasAppRtt && !transportStats.IsAvailable)
            {
                GUI.Box(guiPosition, "IGP Network Monitor");
                GUI.Label(new Rect(guiPosition.x + 10, guiPosition.y + 25, guiPosition.width - 20, 20), 
                    "KCP: 测量中...");
                return;
            }
            
            // 绘制主窗口
            GUI.Box(guiPosition, "IGP Network Monitor");
            
            float y = guiPosition.y + 25;
            float x = guiPosition.x + 10;
            float lineHeight = 20;
            
            // 连接状态
            bool alive = arenaManager.IsKcpAlive;
            string statusIcon = alive ? "✓" : "✗";
            Color statusColor = alive ? Color.green : Color.red;
            
            GUI.contentColor = statusColor;
            GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), 
                $"{statusIcon} {(alive ? "已连接" : "断开")}");
            GUI.contentColor = Color.white;
            y += lineHeight;
            
            // 当前RTT
            if (hasAppRtt)
            {
                GUI.contentColor = appStats!.GetQualityColor();
            }
            GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), 
                hasAppRtt ? $"App RTT: {appStats!.AvgRTT*1000:F0}ms ({appStats.GetQuality()})" : "App RTT: measuring");
            GUI.contentColor = Color.white;
            y += lineHeight;

            GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), FormatKcpRtt(transportStats));
            y += lineHeight;

            GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), FormatQueue(transportStats));
            y += lineHeight;

            GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), FormatUdpRate(transportStats));
            y += lineHeight;

            GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), FormatUdpPacketTotal(transportStats));
            y += lineHeight;

            GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), FormatUdpByteTotal(transportStats));
            y += lineHeight;
            
            // 详细统计
            if (showDetails)
            {
                if (hasAppRtt)
                {
                    GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight),
                        $"App last: {appStats!.LastRTT*1000:F1}ms | avg: {appStats.AvgRTT*1000:F1}ms");
                    y += lineHeight;

                    GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight),
                        $"App min: {appStats.MinRTT*1000:F1}ms | max: {appStats.MaxRTT*1000:F1}ms");
                    y += lineHeight;

                    GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight),
                        $"App samples: {appStats.SampleCount}");
                    y += lineHeight;
                }
            }

            // P2P Peer Latencies
            if (showPeerLatencies && arenaManager.Network != null)
            {
                var peerIds = arenaManager.Network.GetConnectedPeerIds();
                if (peerIds.Count > 0)
                {
                    GUI.Label(new Rect(x, y, guiPosition.width - 20, lineHeight), "--- P2P Latency (Est.) ---");
                    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");
                        y += lineHeight;
                    }
                }
            }

            // Adjust window height if needed (simplified)
            if (y - guiPosition.y > guiPosition.height)
            {
                guiPosition.height = y - guiPosition.y + 10;
            }
        }
        
        /// <summary>
        /// 更新UGUI显示
        /// </summary>
        private void UpdateUGUI()
        {
            if (arenaManager == null)
            {
                return;
            }
            
            // 检查KCP连接
            if (!arenaManager.IsKcpConnected)
            {
                UpdateText(rttText, "KCP: 未连接");
                UpdateText(statusText, "");
                UpdateIndicator(Color.gray);
                UpdateDetailsPanel(false, "");
                return;
            }
            
            var appStats = arenaManager.AppRTTStats;
            var transportStats = arenaManager.KcpTransportStats;
            bool hasAppRtt = appStats != null && appStats.SampleCount > 0;
            if (!hasAppRtt && !transportStats.IsAvailable)
            {
                UpdateText(rttText, "KCP: measuring...");
                UpdateText(statusText, "");
                UpdateIndicator(Color.gray);
                UpdateDetailsPanel(false, "");
                return;
            }
            
            // 更新主显示
            string appText = hasAppRtt
                ? $"App RTT: {appStats!.AvgRTT * 1000f:F0}ms"
                : "App RTT: measuring";
            UpdateText(rttText, $"{appText}\n{FormatKcpRtt(transportStats)}\n{FormatUdpRate(transportStats)}");
            
            // 更新状态
            bool alive = arenaManager.IsKcpAlive;
            UpdateText(statusText, alive ? "✓ 已连接" : "✗ 断开", alive ? Color.green : Color.red);
            
            // 更新质量指示器
            UpdateIndicator(hasAppRtt ? appStats!.GetQualityColor() : Color.yellow);
            
            // 更新详细面板
            if (showDetails)
            {
                string details = hasAppRtt
                    ? $"App quality: {appStats!.GetQuality()}\n" +
                      $"App last RTT: {appStats.LastRTT*1000:F1}ms\n" +
                      $"App avg RTT: {appStats.AvgRTT*1000:F1}ms\n" +
                      $"App min RTT: {appStats.MinRTT*1000:F1}ms\n" +
                      $"App max RTT: {appStats.MaxRTT*1000:F1}ms\n" +
                      $"App samples: {appStats.SampleCount}"
                    : "App RTT: measuring";

                details += $"\n{FormatKcpRtt(transportStats)}\n{FormatQueue(transportStats)}\n{FormatUdpRate(transportStats)}\n{FormatUdpPacketTotal(transportStats)}\n{FormatUdpByteTotal(transportStats)}";

                if (showPeerLatencies && arenaManager.Network != null)
                {
                    var peerIds = arenaManager.Network.GetConnectedPeerIds();
                    if (peerIds.Count > 0)
                    {
                        details += "\n\n--- P2P Latency (Est.) ---";
                        foreach (var peerId in peerIds)
                        {
                            uint latency = arenaManager.Network.GetPeerLatency(new IGP.UnitySDK.Network.IGPPlayerID(peerId));
                            details += $"\n{peerId.Substring(Mathf.Max(0, peerId.Length - 6))}: {latency}ms";
                        }
                    }
                }
                UpdateDetailsPanel(true, details);
            }
            else
            {
                UpdateDetailsPanel(false, "");
            }
        }
        
        private void UpdateText(Text? text, string content, Color? color = null)
        {
            if (text != null)
            {
                text.text = content;
                if (color.HasValue)
                {
                    text.color = color.Value;
                }
            }
        }
        
        private void UpdateIndicator(Color color)
        {
            if (qualityIndicator != null)
            {
                qualityIndicator.color = color;
            }
        }
        
        private void UpdateDetailsPanel(bool show, string details)
        {
            if (detailsPanel != null)
            {
                detailsPanel.SetActive(show);
            }
            
            if (detailsText != null)
            {
                detailsText.text = details;
            }
        }

        private static string FormatKcpRtt(IGPKcpTransportStats stats)
        {
            if (!stats.IsAvailable)
            {
                return "KCP RTT: --";
            }

            return stats.HasSmoothedRtt
                ? $"KCP RTT: srtt {stats.SmoothedRttMs}ms | rto {stats.RtoMs}ms"
                : $"KCP RTT: srtt -- | rto {stats.RtoMs}ms";
        }

        private static string FormatQueue(IGPKcpTransportStats stats)
        {
            return stats.IsAvailable
                ? $"Queue: wait {stats.WaitSnd} | q {stats.SndQueue} | buf {stats.SndBuf}"
                : "Queue: --";
        }

        private static string FormatUdpRate(IGPKcpTransportStats stats)
        {
            return stats.IsAvailable
                ? $"UDP: in {stats.DatagramsInPerSecond:F0}/s | out {stats.DatagramsOutPerSecond:F0}/s"
                : "UDP: --";
        }

        private static string FormatUdpPacketTotal(IGPKcpTransportStats stats)
        {
            return stats.IsAvailable
                ? $"UDP pkts: in {IGPRTTDisplayFormatting.FormatUdpDatagramCount(stats.DatagramsIn)} | out {IGPRTTDisplayFormatting.FormatUdpDatagramCount(stats.DatagramsOut)}"
                : "UDP pkts: --";
        }

        private static string FormatUdpByteTotal(IGPKcpTransportStats stats)
        {
            return stats.IsAvailable
                ? $"UDP bytes: in {IGPRTTDisplayFormatting.FormatByteCount(stats.DatagramBytesIn)} | out {IGPRTTDisplayFormatting.FormatByteCount(stats.DatagramBytesOut)}"
                : "UDP bytes: --";
        }
        
        /// <summary>
        /// 切换详细统计显示
        /// </summary>
        public void ToggleDetails()
        {
            showDetails = !showDetails;
        }
        
        /// <summary>
        /// 重置RTT统计
        /// </summary>
        public void ResetStats()
        {
            if (arenaManager?.AppRTTStats != null)
            {
                arenaManager.AppRTTStats.Reset();
                Debug.Log("[IGP RTT Display] Stats reset");
            }
        }
    }
}
