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

namespace EventsAppQuest.Web.Presentation
{
    /// <summary>
    /// Painel do dashboard consolidado do ciclo completo: Quest → Hotel → Produtor → Aceite Final. Apenas agregador visual.
    /// </summary>
    public class EventCycleDashboardPanel : 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 titleRow = new GameObject("TitleRow");
            titleRow.transform.SetParent(_content, false);
            titleRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 28);
            var hLayout = titleRow.AddComponent<HorizontalLayoutGroup>();
            hLayout.spacing = 8;
            hLayout.childForceExpandWidth = false;
            hLayout.childForceExpandHeight = true;
            var label = new GameObject("Label");
            label.transform.SetParent(titleRow.transform, false);
            var labelLe = label.AddComponent<LayoutElement>();
            labelLe.flexibleWidth = 1;
            labelLe.preferredHeight = 24;
            var labelText = label.AddComponent<Text>();
            labelText.text = "Dashboard consolidado do ciclo (Quest → Hotel → Produtor → Aceite Final)";
            labelText.font = font;
            labelText.fontSize = 16;
            labelText.fontStyle = FontStyle.Bold;
            var refreshBtn = new GameObject("RefreshBtn");
            refreshBtn.transform.SetParent(titleRow.transform, false);
            var btnLe = refreshBtn.AddComponent<LayoutElement>();
            btnLe.preferredWidth = 80;
            btnLe.preferredHeight = 22;
            var btnImg = refreshBtn.AddComponent<Image>();
            btnImg.color = new Color(0.4f, 0.7f, 0.5f);
            var btn = refreshBtn.AddComponent<Button>();
            btn.targetGraphic = btnImg;
            btn.onClick.AddListener(Refresh);
            var btnTextGo = new GameObject("Text");
            btnTextGo.transform.SetParent(refreshBtn.transform, false);
            var btnTextRt = btnTextGo.AddComponent<RectTransform>();
            btnTextRt.anchorMin = Vector2.zero;
            btnTextRt.anchorMax = Vector2.one;
            btnTextRt.offsetMin = Vector2.zero;
            btnTextRt.offsetMax = Vector2.zero;
            var btnText = btnTextGo.AddComponent<Text>();
            btnText.text = "Atualizar";
            btnText.font = font;
            btnText.fontSize = 10;
            btnText.alignment = TextAnchor.MiddleCenter;

            var orders = HandoffStore.GetOrders();
            var opportunities = data.GetOpportunities();
            var proposals = data.GetProposals();
            var sessions = data.GetSessions();
            var followUps = data.GetFollowUpTasks();
            var states = EventCycleDashboardController.BuildDashboard(orders, opportunities, proposals, sessions);
            var alertStates = EventCycleAlertController.EvaluateAllAlerts(orders, opportunities, proposals, sessions, followUps);
            var actionPlans = EventCycleActionPlanController.GenerateActionPlans(orders, opportunities, proposals, sessions, followUps);
            var summaries = EventCycleExecutiveSummaryController.GenerateSummaries(orders, opportunities, proposals, sessions, followUps);
            var closures = EventCycleClosureController.EvaluateClosure(orders, opportunities, proposals, sessions, followUps);
            var metricsList = EventCycleMetricsController.CalculateMetrics(orders, opportunities, proposals, sessions, followUps);
            var benchmark = EventCycleBenchmarkController.BuildBenchmark(orders, opportunities, proposals, sessions, followUps);
            var slaList = EventCycleSLAController.EvaluateSLA(orders, opportunities, proposals, sessions, followUps);
            var dependencyMaps = EventCycleDependencyMapController.BuildMaps(orders, opportunities, proposals, sessions, followUps);
            var bottleneckStates = EventCycleBottleneckController.EvaluateBottlenecks(orders, opportunities, proposals, sessions, followUps);
            var recoveryPlans = EventCycleRecoveryPlanController.GenerateRecoveryPlans(orders, opportunities, proposals, sessions, followUps);
            var scenarioComparisons = EventCycleScenarioSimulationController.RunSimulations(orders, opportunities, proposals, sessions, followUps);
            var portfolioState = EventCyclePortfolioPriorityController.BuildPortfolioPriority(orders, opportunities, proposals, sessions, followUps);

            if (states.Count == 0)
            {
                var empty = new GameObject("Empty");
                empty.transform.SetParent(_content, false);
                var emptyText = empty.AddComponent<Text>();
                emptyText.font = font;
                emptyText.fontSize = 12;
                emptyText.text = "Nenhum pedido no handoff. Gere um pedido a partir de uma oportunidade para ver o ciclo.";
                empty.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 20);
                return;
            }

            if (benchmark != null && benchmark.Entries != null && benchmark.Entries.Count > 0)
            {
                var benchRow = new GameObject("BenchmarkSummary");
                benchRow.transform.SetParent(_content, false);
                var benchText = benchRow.AddComponent<Text>();
                benchText.font = font;
                benchText.fontSize = 11;
                var bestId = benchmark.BestPerformingEntry?.CycleId ?? "—";
                var bestScore = benchmark.BestPerformingEntry != null ? benchmark.BestPerformingEntry.OverallCyclePerformanceScore.ToString() : "—";
                var worstId = benchmark.LowestPerformingEntry?.CycleId ?? "—";
                var worstScore = benchmark.LowestPerformingEntry != null ? benchmark.LowestPerformingEntry.OverallCyclePerformanceScore.ToString() : "—";
                var topPattern = (benchmark.TopPatterns != null && benchmark.TopPatterns.Count > 0) ? benchmark.TopPatterns[0] : "";
                var riskPattern = (benchmark.RiskPatterns != null && benchmark.RiskPatterns.Count > 0) ? benchmark.RiskPatterns[0] : "";
                benchText.text = $"Benchmark: Média {benchmark.AveragePerformanceScore:F1} | Melhor {bestId} ({bestScore}) | Pior {worstId} ({worstScore}) | + {topPattern} | − {riskPattern} | {(benchmark.LastBenchmarkedAt?.ToString("yyyy-MM-dd HH:mm") ?? "—")}";
                benchRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
            }

            if (portfolioState != null && portfolioState.Items != null && portfolioState.Items.Count > 0)
            {
                var portRow = new GameObject("PortfolioPriority");
                portRow.transform.SetParent(_content, false);
                var portText = portRow.AddComponent<Text>();
                portText.font = font;
                portText.fontSize = 11;
                var priTitle = portfolioState.HighestPriorityItem?.Title ?? "—";
                var critTitle = portfolioState.HighestRiskItem?.Title ?? "—";
                var recTitle = portfolioState.BestRecoveryOpportunity?.Title ?? "—";
                portText.text = $"Fila: Prioritário {priTitle} | Mais crítico {critTitle} | Melhor recuperação {recTitle} | {(portfolioState.LastPrioritizedAt?.ToString("yyyy-MM-dd HH:mm") ?? "—")}";
                portRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
            }

            var overviewState = portfolioState != null ? EventCyclePortfolioOverviewController.BuildOverviewFromPriorityState(portfolioState, portfolioState.LastPrioritizedAt) : null;
            if (overviewState != null && overviewState.TotalCycles > 0)
            {
                var overRow = new GameObject("PortfolioOverview");
                overRow.transform.SetParent(_content, false);
                var overText = overRow.AddComponent<Text>();
                overText.font = font;
                overText.fontSize = 11;
                var critGroup = overviewState.Groups?.Find(g => g.GroupKey == EventCyclePortfolioOverviewController.GroupBlocked) ?? overviewState.Groups?.Find(g => g.GroupKey == EventCyclePortfolioOverviewController.GroupAtRisk);
                var largestGroup = overviewState.Groups?.Count > 0 ? overviewState.Groups[0] : null;
                var critTitle = critGroup?.Title ?? "—";
                var largeTitle = largestGroup?.Title ?? "—";
                var largeCount = largestGroup?.ItemCount ?? 0;
                overText.text = $"Carteira: {overviewState.TotalCycles} ciclo(s) | Em andamento {overviewState.InProgressCount} | Em risco {overviewState.AtRiskCount} | Bloqueados {overviewState.BlockedCount} | Crítico: {critTitle} | Maior grupo: {largeTitle} ({largeCount}) | {(overviewState.LastUpdatedAt?.ToString("yyyy-MM-dd HH:mm") ?? "—")}";
                overRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
            }

            var filteredState = portfolioState != null ? EventCyclePortfolioFilterController.ApplyActiveFilterOrNone(portfolioState) : null;
            if (filteredState != null && filteredState.ActiveFilter != null)
            {
                var filtRow = new GameObject("PortfolioFilter");
                filtRow.transform.SetParent(_content, false);
                var filtText = filtRow.AddComponent<Text>();
                filtText.font = font;
                filtText.fontSize = 11;
                var topTitle = filteredState.HighestPriorityFilteredItem?.Title ?? "—";
                filtText.text = $"Filtro ativo: {filteredState.ActiveFilter.Name} | {filteredState.FilteredCount} item(ns) | Crítico no recorte: {topTitle} | {(filteredState.LastFilteredAt?.ToString("yyyy-MM-dd HH:mm") ?? "—")}";
                filtRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
            }

            var watchState = EventCycleWatchlistController.GetWatchlistState(portfolioState);
            if (watchState.TotalWatched > 0)
            {
                var watchRow = new GameObject("Watchlist");
                watchRow.transform.SetParent(_content, false);
                var watchText = watchRow.AddComponent<Text>();
                watchText.font = font;
                watchText.fontSize = 11;
                var favCount = watchState.FavoriteItems?.Count ?? 0;
                var topPinned = watchState.TopPinnedItem?.Title ?? "—";
                watchText.text = $"Watchlist: {watchState.TotalWatched} observado(s) | {favCount} favorito(s) | Fixado: {topPinned} | {(watchState.LastUpdatedAt?.ToString("yyyy-MM-dd HH:mm") ?? "—")}";
                watchRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
            }

            var notesState = EventCycleManagerNotesController.GetGlobalNotesState();
            if (notesState.TotalNotes > 0)
            {
                var notesRow = new GameObject("ManagerNotes");
                notesRow.transform.SetParent(_content, false);
                var notesText = notesRow.AddComponent<Text>();
                notesText.font = font;
                notesText.fontSize = 11;
                var pinnedTitle = notesState.TopPinnedItem != null ? notesState.TopPinnedItem.Title + " [" + notesState.TopPinnedItem.CycleId + "]" : "—";
                notesText.text = $"Notas gerenciais: {notesState.TotalNotes} nota(s) | Fixada: {pinnedTitle} | {(notesState.LastUpdatedAt?.ToString("yyyy-MM-dd HH:mm") ?? "—")}";
                notesRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
            }

            var snapsState = EventCycleExecutiveSnapshotsController.GetGlobalSnapshotsState();
            if (snapsState.TotalSnapshots > 0)
            {
                var snapRow = new GameObject("ExecutiveSnapshots");
                snapRow.transform.SetParent(_content, false);
                var snapText = snapRow.AddComponent<Text>();
                snapText.font = font;
                snapText.fontSize = 11;
                var latest = snapsState.LatestSnapshot;
                var latestLabel = latest != null ? (latest.Title + " [" + latest.CycleId + "]") : "—";
                snapText.text = $"Snapshots: {snapsState.TotalSnapshots} | Último: {latestLabel} | {(snapsState.LastCapturedAt?.ToString(\"yyyy-MM-dd HH:mm\") ?? \"—\")}";
                snapRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
            }

            var evoState = EventCycleSnapshotComparisonController.GetGlobalComparisonState();
            if (evoState.TotalComparisons > 0 && evoState.LatestComparison != null)
            {
                var evoRow = new GameObject("SnapshotEvolution");
                evoRow.transform.SetParent(_content, false);
                var evoText = evoRow.AddComponent<Text>();
                evoText.font = font;
                evoText.fontSize = 11;
                var c = evoState.LatestComparison;
                evoText.text = $"Evolução: {c.OverallDirection} [{c.CycleId}] | + {c.MainImprovement ?? \"—\"} | − {c.MainRegression ?? \"—\"} | {(c.ComparedAt?.ToString(\"yyyy-MM-dd HH:mm\") ?? \"—\")}";
                evoRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
            }

            var decisionTrailState = EventCycleExecutiveDecisionTrailController.GetGlobalTrailState();
            if (decisionTrailState.TotalDecisions > 0 && decisionTrailState.LatestDecision != null)
            {
                var trailRow = new GameObject("ExecutiveDecisionTrail");
                trailRow.transform.SetParent(_content, false);
                var trailText = trailRow.AddComponent<Text>();
                trailText.font = font;
                trailText.fontSize = 11;
                var dt = decisionTrailState.LatestDecision;
                trailText.text = $"Trilha de decisões: {decisionTrailState.TotalDecisions} decisão(ões) | Última [{dt.CycleId}] {dt.Title} | {dt.DecisionOutcome} | {(decisionTrailState.LastDecisionAt?.ToString("yyyy-MM-dd HH:mm") ?? "—")}";
                trailRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
            }

            foreach (var state in states)
            {
                var block = new GameObject("Cycle_" + state.ProducerOrderId);
                block.transform.SetParent(_content, false);
                var layout = block.AddComponent<VerticalLayoutGroup>();
                layout.spacing = 4;
                layout.childForceExpandHeight = false;
                layout.childForceExpandWidth = true;

                var header = new GameObject("Header");
                header.transform.SetParent(block.transform, false);
                var headerText = header.AddComponent<Text>();
                headerText.font = font;
                headerText.fontSize = 14;
                headerText.fontStyle = FontStyle.Bold;
                headerText.text = $"{state.ProducerOrderId} | {state.OverallCycleStatus} | {state.OperationalStageLabel} | Atualizado: {(state.LastUpdatedAt?.ToString("yyyy-MM-dd HH:mm") ?? "—")}";
                header.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 20);

                var execSummary = summaries?.Find(s => s.CycleId == state.ProducerOrderId);
                if (execSummary != null)
                {
                    EventCycleExecutiveSummaryController.GetMainRiskAndAction(execSummary, out var mainRisk, out var mainAction);
                    var execRow = new GameObject("ExecSummary");
                    execRow.transform.SetParent(block.transform, false);
                    var execText = execRow.AddComponent<Text>();
                    execText.font = font;
                    execText.fontSize = 11;
                    execText.text = $"Resumo executivo: {execSummary.OverallStatusLabel} | Risco: {(mainRisk != null ? mainRisk.Title : "—")} | Próxima ação: {(mainAction != null ? mainAction.Title : "—")}";
                    execRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
                }

                var closure = closures?.Find(c => c.CycleId == state.ProducerOrderId);
                if (closure != null)
                {
                    var closureRow = new GameObject("Closure");
                    closureRow.transform.SetParent(block.transform, false);
                    var closureText = closureRow.AddComponent<Text>();
                    closureText.font = font;
                    closureText.fontSize = 11;
                    var healthyLabel = closure.IsCycleHealthy ? "Saudável" : (closure.IsCycleBlocked ? "Bloqueado" : (closure.IsCycleAtRisk ? "Em risco" : "Em andamento"));
                    closureText.text = $"Estado global: {closure.ClosureStatus} ({healthyLabel}) | Recomendação: {closure.ClosingRecommendation}";
                    if (closure.IsCycleBlocked) closureText.color = new Color(0.75f, 0.2f, 0.2f);
                    else if (closure.IsCycleAtRisk) closureText.color = new Color(0.7f, 0.4f, 0f);
                    closureRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
                }

                var trailState = EventCycleExecutiveDecisionTrailController.GetTrailState(state.ProducerOrderId);
                if (trailState.TotalDecisions > 0)
                {
                    var decRow = new GameObject("DecisionTrail");
                    decRow.transform.SetParent(block.transform, false);
                    var decText = decRow.AddComponent<Text>();
                    decText.font = font;
                    decText.fontSize = 11;
                    var latestDec = trailState.LatestDecision;
                    var decTitle = latestDec != null ? latestDec.Title : "—";
                    var decOutcome = latestDec != null ? latestDec.DecisionOutcome.ToString() : "—";
                    decText.text = $"Decisões: {trailState.TotalDecisions} | Última: {decTitle} | {decOutcome} | {(trailState.LastDecisionAt?.ToString("yyyy-MM-dd HH:mm") ?? "—")}";
                    decRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
                }

                var metrics = metricsList?.Find(m => m.CycleId == state.ProducerOrderId);
                if (metrics != null)
                {
                    EventCycleMetricsController.GetTopFactor(metrics, out var topPos, out var topNeg);
                    var metricsRow = new GameObject("Metrics");
                    metricsRow.transform.SetParent(block.transform, false);
                    var metricsText = metricsRow.AddComponent<Text>();
                    metricsText.font = font;
                    metricsText.fontSize = 11;
                    metricsText.text = $"Performance: Score {metrics.OverallCyclePerformanceScore} ({metrics.PerformanceLabel}) | + {topPos ?? "—"} | − {topNeg ?? "—"} | {(metrics.LastCalculatedAt?.ToString("yyyy-MM-dd HH:mm") ?? "—")}";
                    metricsRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
                }

                var sla = slaList?.Find(s => s.CycleId == state.ProducerOrderId);
                if (sla != null && sla.DelayRiskLevel != EventCycleDelaySeverity.None)
                {
                    var slaRow = new GameObject("SLA");
                    slaRow.transform.SetParent(block.transform, false);
                    var slaText = slaRow.AddComponent<Text>();
                    slaText.font = font;
                    slaText.fontSize = 11;
                    slaText.text = $"SLA: Risco {sla.DelayRiskLevel} | {sla.MainDelayReason ?? "—"} | {(sla.LastEvaluatedAt?.ToString("yyyy-MM-dd HH:mm") ?? "—")}";
                    if (sla.DelayRiskLevel == EventCycleDelaySeverity.Critical || sla.DelayRiskLevel == EventCycleDelaySeverity.High)
                        slaText.color = new Color(0.75f, 0.2f, 0.2f);
                    slaRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
                }

                var depMap = dependencyMaps?.Find(m => m.CycleId == state.ProducerOrderId);
                if (depMap != null && (depMap.MostCriticalDependency != null || (depMap.BlockingNodes != null && depMap.BlockingNodes.Count > 0)))
                {
                    var depRow = new GameObject("Dependencies");
                    depRow.transform.SetParent(block.transform, false);
                    var depText = depRow.AddComponent<Text>();
                    depText.font = font;
                    depText.fontSize = 11;
                    var critStr = depMap.MostCriticalDependency != null ? $"{depMap.MostCriticalDependency.FromNodeId}→{depMap.MostCriticalDependency.ToNodeId}" : "—";
                    var blockCount = depMap.BlockingNodes?.Count ?? 0;
                    depText.text = $"Dependências: crítica {critStr} | {blockCount} nó(s) bloqueante(s) | {(depMap.LastEvaluatedAt?.ToString("yyyy-MM-dd HH:mm") ?? "—")}";
                    if (depMap.MostCriticalDependency != null && depMap.MostCriticalDependency.IsCurrentlyBlocked)
                        depText.color = new Color(0.65f, 0.2f, 0.2f);
                    depRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
                }

                var bottlenecks = bottleneckStates?.Find(b => b.CycleId == state.ProducerOrderId);
                if (bottlenecks != null && bottlenecks.TopPriorityBottleneck != null)
                {
                    var bnRow = new GameObject("Bottlenecks");
                    bnRow.transform.SetParent(block.transform, false);
                    var bnText = bnRow.AddComponent<Text>();
                    bnText.font = font;
                    bnText.fontSize = 11;
                    bnText.text = $"Gargalo: {bottlenecks.TopPriorityBottleneck.Title} | Ação: {bottlenecks.TopPriorityBottleneck.SuggestedResolution} | {(bottlenecks.LastEvaluatedAt?.ToString("yyyy-MM-dd HH:mm") ?? "—")}";
                    if (bottlenecks.TopPriorityBottleneck.Severity == EventCycleBottleneckSeverity.Critical || bottlenecks.TopPriorityBottleneck.Severity == EventCycleBottleneckSeverity.High)
                        bnText.color = new Color(0.7f, 0.2f, 0.2f);
                    bnRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
                }

                var recoveryPlan = recoveryPlans?.Find(r => r.CycleId == state.ProducerOrderId);
                if (recoveryPlan != null && recoveryPlan.IsRecoveryNeeded && recoveryPlan.PrimaryRecoveryAction != null)
                {
                    var recRow = new GameObject("Recovery");
                    recRow.transform.SetParent(block.transform, false);
                    var recText = recRow.AddComponent<Text>();
                    recText.font = font;
                    recText.fontSize = 11;
                    recText.text = $"Recuperação: Sim | Principal: {recoveryPlan.PrimaryRecoveryAction.Title} | Confiança: {recoveryPlan.RecoveryConfidenceLabel} | {(recoveryPlan.LastGeneratedAt?.ToString("yyyy-MM-dd HH:mm") ?? "—")}";
                    if (recoveryPlan.PrimaryRecoveryAction.Priority == EventCycleRecoveryPriority.Urgent || recoveryPlan.PrimaryRecoveryAction.Priority == EventCycleRecoveryPriority.High)
                        recText.color = new Color(0.65f, 0.2f, 0.2f);
                    recRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
                }

                var scenarioComp = scenarioComparisons?.Find(c => c.CycleId == state.ProducerOrderId);
                if (scenarioComp != null && scenarioComp.RecommendedScenario != null)
                {
                    var simRow = new GameObject("Scenario");
                    simRow.transform.SetParent(block.transform, false);
                    var simText = simRow.AddComponent<Text>();
                    simText.font = font;
                    simText.fontSize = 11;
                    simText.text = $"Cenário recomendado: {scenarioComp.RecommendedScenario.ScenarioName} | Impacto: {scenarioComp.RecommendedScenario.PredictedImpactSummary} | Ganho: {scenarioComp.BestImprovementDelta} | {(scenarioComp.LastSimulatedAt?.ToString("yyyy-MM-dd HH:mm") ?? "—")}";
                    simRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
                }

                if (state.Sections != null)
                {
                    foreach (var section in state.Sections)
                    {
                        var secGo = new GameObject("Sec_" + section.SectionKey);
                        secGo.transform.SetParent(block.transform, false);
                        var secText = secGo.AddComponent<Text>();
                        secText.font = font;
                        secText.fontSize = 11;
                        secText.text = $"[{section.Title}] {section.StatusLabel} — {section.Summary} {(section.IsHealthy ? "✓" : "!")}";
                        if (!string.IsNullOrEmpty(section.Notes))
                            secText.text += " | " + section.Notes;
                        secGo.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
                    }
                }

                var cyclePlan = actionPlans.Find(p => p.CycleId == state.ProducerOrderId);
                if (cyclePlan != null && cyclePlan.TopPriorityAction != null)
                {
                    var actionRow = new GameObject("NextAction");
                    actionRow.transform.SetParent(block.transform, false);
                    var actionText = actionRow.AddComponent<Text>();
                    actionText.font = font;
                    actionText.fontSize = 10;
                    actionText.fontStyle = FontStyle.Bold;
                    actionText.text = $"Próxima ação: {cyclePlan.TopPriorityAction.Title} ({cyclePlan.TopPriorityAction.ResponsibleRole}) — {cyclePlan.TopPriorityAction.SuggestedReason}";
                    actionRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 14);
                }

                var cycleAlerts = alertStates.Find(a => a.CycleId == state.ProducerOrderId);
                if (cycleAlerts != null && cycleAlerts.TotalAlerts > 0)
                {
                    var alertRow = new GameObject("AlertSummary");
                    alertRow.transform.SetParent(block.transform, false);
                    var alertText = alertRow.AddComponent<Text>();
                    alertText.font = font;
                    alertText.fontSize = 10;
                    alertText.text = $"Alertas: {cycleAlerts.TotalAlerts} (críticos: {cycleAlerts.Alerts.FindAll(x => x.Severity == EventCycleAlertSeverity.Critical).Count}, bloqueantes: {cycleAlerts.BlockingAlerts})";
                    if (cycleAlerts.BlockingAlerts > 0) alertText.color = new Color(0.75f, 0.2f, 0.2f);
                    alertRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 14);
                    foreach (var al in cycleAlerts.Alerts)
                    {
                        if (cycleAlerts.Alerts.IndexOf(al) >= 2) break;
                        var alRow = new GameObject("Alert_" + al.AlertId);
                        alRow.transform.SetParent(block.transform, false);
                        var alText = alRow.AddComponent<Text>();
                        alText.font = font;
                        alText.fontSize = 9;
                        alText.text = "  → " + al.Title + ": " + (al.SuggestedAction ?? "—");
                        alRow.GetComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
                    }
                }
            }
        }

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