using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using EventsAppQuest.Web.Application;
using EventsAppQuest.Web.Domain;
using EventsAppQuest.Web.Producer.Application;

namespace EventsAppQuest.Web.Presentation
{
    /// <summary>
    /// Painel de benchmark interno: lista de entradas, melhor/pior caso, média, padrões positivos e de risco.
    /// </summary>
    public class EventCycleBenchmarkPanel : MonoBehaviour, IWebContentRoot
    {
        private Transform _content;

        public void SetContentRoot(Transform contentRoot) => _content = contentRoot;

        private void Start()
        {
            Refresh();
            WebRuntimeContext.OnDataChanged += Refresh;
        }

        private void OnDestroy() => WebRuntimeContext.OnDataChanged -= Refresh;

        public void Refresh()
        {
            if (_content == null) return;
            ClearContent(_content);
            var data = WebRuntimeContext.DataService;
            if (data == null) return;
            var font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");

            var orders = HandoffStore.GetOrders();
            var opportunities = data.GetOpportunities();
            var proposals = data.GetProposals();
            var sessions = data.GetSessions();
            var followUps = data.GetFollowUpTasks();
            var benchmark = EventCycleBenchmarkController.BuildBenchmark(orders, opportunities, proposals, sessions, followUps);

            var titleRow = new GameObject("TitleRow");
            titleRow.transform.SetParent(_content, false);
            titleRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 26);
            var titleText = titleRow.AddComponent<Text>();
            titleText.text = "Benchmark interno do ciclo (comparação entre casos/sessões)";
            titleText.font = font;
            titleText.fontSize = 16;
            titleText.fontStyle = FontStyle.Bold;

            var btnRow = new GameObject("BtnRow");
            btnRow.transform.SetParent(_content, false);
            btnRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 24);
            var hLayout = btnRow.AddComponent<HorizontalLayoutGroup>();
            hLayout.spacing = 6;
            hLayout.childForceExpandWidth = false;
            CreateSmallButton(btnRow.transform, "Recalcular", font, 80, Refresh);

            if (benchmark == null || benchmark.Entries == null || benchmark.Entries.Count == 0)
            {
                var empty = new GameObject("Empty");
                empty.transform.SetParent(_content, false);
                var emptyText = empty.AddComponent<Text>();
                emptyText.font = font;
                emptyText.fontSize = 11;
                emptyText.text = "Nenhum ciclo para benchmark. Gere pedidos para comparar.";
                empty.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 18);
                return;
            }

            AddBlock(_content, font, "Resumo", benchmark.ComparisonSummary ?? "—");
            AddBlock(_content, font, "Média", $"Score médio: {benchmark.AveragePerformanceScore:F1}");
            if (benchmark.BestPerformingEntry != null)
                AddBlock(_content, font, "Melhor caso", $"{benchmark.BestPerformingEntry.CycleId} — Score {benchmark.BestPerformingEntry.OverallCyclePerformanceScore} ({benchmark.BestPerformingEntry.PerformanceLabel})");
            if (benchmark.LowestPerformingEntry != null)
                AddBlock(_content, font, "Pior caso", $"{benchmark.LowestPerformingEntry.CycleId} — Score {benchmark.LowestPerformingEntry.OverallCyclePerformanceScore} ({benchmark.LowestPerformingEntry.PerformanceLabel})");

            var listLabel = new GameObject("ListLabel");
            listLabel.transform.SetParent(_content, false);
            var listLabelText = listLabel.AddComponent<Text>();
            listLabelText.font = font;
            listLabelText.fontSize = 11;
            listLabelText.fontStyle = FontStyle.Bold;
            listLabelText.text = "Entradas (vs média):";
            listLabel.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);

            foreach (var e in benchmark.Entries)
            {
                var diff = EventCycleBenchmarkController.CompareEntryToAverage(e, benchmark);
                var diffStr = diff >= 0 ? "+" + diff : diff.ToString();
                var row = new GameObject("Entry_" + e.CycleId);
                row.transform.SetParent(_content, false);
                var rowText = row.AddComponent<Text>();
                rowText.font = font;
                rowText.fontSize = 10;
                rowText.text = $"{e.CycleId} | Score {e.OverallCyclePerformanceScore} ({e.PerformanceLabel}) | vs média {diffStr}";
                row.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 14);
            }

            if (benchmark.TopPatterns != null && benchmark.TopPatterns.Count > 0)
            {
                var topLabel = new GameObject("TopPatternsLabel");
                topLabel.transform.SetParent(_content, false);
                var topLabelText = topLabel.AddComponent<Text>();
                topLabelText.font = font;
                topLabelText.fontSize = 11;
                topLabelText.fontStyle = FontStyle.Bold;
                topLabelText.text = "Padrões positivos:";
                topLabelText.color = new Color(0.2f, 0.5f, 0.2f);
                topLabel.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
                foreach (var p in benchmark.TopPatterns)
                {
                    var line = new GameObject("Pattern");
                    line.transform.SetParent(_content, false);
                    var lineText = line.AddComponent<Text>();
                    lineText.font = font;
                    lineText.fontSize = 10;
                    lineText.text = "  • " + p;
                    lineText.color = new Color(0.2f, 0.5f, 0.2f);
                    line.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 14);
                }
            }
            if (benchmark.RiskPatterns != null && benchmark.RiskPatterns.Count > 0)
            {
                var riskLabel = new GameObject("RiskPatternsLabel");
                riskLabel.transform.SetParent(_content, false);
                var riskLabelText = riskLabel.AddComponent<Text>();
                riskLabelText.font = font;
                riskLabelText.fontSize = 11;
                riskLabelText.fontStyle = FontStyle.Bold;
                riskLabelText.text = "Padrões de risco:";
                riskLabelText.color = new Color(0.6f, 0.2f, 0.2f);
                riskLabel.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
                foreach (var p in benchmark.RiskPatterns)
                {
                    var line = new GameObject("RiskPattern");
                    line.transform.SetParent(_content, false);
                    var lineText = line.AddComponent<Text>();
                    lineText.font = font;
                    lineText.fontSize = 10;
                    lineText.text = "  • " + p;
                    lineText.color = new Color(0.6f, 0.2f, 0.2f);
                    line.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 14);
                }
            }

            var tsRow = new GameObject("Timestamp");
            tsRow.transform.SetParent(_content, false);
            var tsText = tsRow.AddComponent<Text>();
            tsText.font = font;
            tsText.fontSize = 10;
            tsText.text = "Benchmark: " + (benchmark.LastBenchmarkedAt?.ToString("yyyy-MM-dd HH:mm") ?? "—");
            tsRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 14);
        }

        private static void AddBlock(Transform parent, Font font, string title, string content)
        {
            var go = new GameObject("Block_" + title);
            go.transform.SetParent(parent, false);
            var text = go.AddComponent<Text>();
            text.font = font;
            text.fontSize = 10;
            text.text = title + ": " + (content ?? "—");
            go.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 14);
        }

        private static void CreateSmallButton(Transform parent, string text, Font font, float width, System.Action onClick)
        {
            var go = new GameObject("Btn_" + text);
            go.transform.SetParent(parent, false);
            var rt = go.AddComponent<RectTransform>();
            rt.sizeDelta = new Vector2(width, 22);
            var le = go.AddComponent<LayoutElement>();
            le.preferredWidth = width;
            le.preferredHeight = 22;
            var img = go.AddComponent<Image>();
            img.color = new Color(0.4f, 0.7f, 0.5f);
            var btn = go.AddComponent<Button>();
            btn.targetGraphic = img;
            btn.onClick.AddListener(() => onClick?.Invoke());
            var tGo = new GameObject("Text");
            tGo.transform.SetParent(go.transform, false);
            var tRt = tGo.AddComponent<RectTransform>();
            tRt.anchorMin = Vector2.zero;
            tRt.anchorMax = Vector2.one;
            tRt.offsetMin = Vector2.zero;
            tRt.offsetMax = Vector2.zero;
            var t = tGo.AddComponent<Text>();
            t.text = text;
            t.font = font;
            t.fontSize = 9;
            t.alignment = TextAnchor.MiddleCenter;
        }

        private static void ClearContent(Transform content)
        {
            for (var i = content.childCount - 1; i >= 0; i--)
                Destroy(content.GetChild(i).gameObject);
        }
    }
}
