using UnityEngine;
using UnityEngine.UI;
using EventsAppQuest.Core;
using EventsAppQuest.Domain.Enums;

namespace EventsAppQuest.Presentation
{
    /// <summary>
    /// HUD da cena Quest compatível com headset: menos informação por vez, blocos grandes, destaque do passo/hotspot/estado atual,
    /// indicador de progresso e área de status (modo, prontidão para build Quest).
    /// </summary>
    public class QuestPresentationHUD : MonoBehaviour
    {
        private const string ModoGuiado = "Guiado";
        private const string ModoManual = "Manual";
        private const string ModoHotspot = "Foco hotspot";

        private const string ModoTesteQuest = "Modo: Teste Quest inicial";
        private Text _titleText;
        private Text _blockLabelText;
        private Text _blockContentText;
        private Text _progressText;
        private Text _statusText;
        private Text _readinessText;
        private Text _focusIndicatorText;
        private Text _selectionIndicatorText;
        private Text _pointedTargetText;
        private Text _inputDebugText;
        private Text _xrDebugText;
        private Text _xrInputDebugText;
        private Text _xrRaycastDebugText;
        private Text _hoverDwellDebugText;
        private Text _targetingDebugText;
        private Text _gazeLikeDebugText;
        private Text _hotspotContextDebugText;
        private Text _comparisonDebugText;
        private Text _closingDebugText;
        private Text _commercialOutcomeDebugText;
        private Text _exportDebugText;
        private Text _persistenceDebugText;
        private Text _handoffDebugText;
        private Text _shareableDebugText;
        private Text _qualityDebugText;
        private Text _improvementDebugText;
        private Text _presetDebugText;
        private Text _onboardingDebugText;
        private Text _shortFlowDebugText;
        private Image _blockHighlight;
        private Font _font;

        /// <summary>Se true, mostra linha de debug do fechamento imersivo.</summary>
        public bool ShowClosingDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug do resultado comercial da sessão (estado, CTA, proposta, prioridade).</summary>
        public bool ShowCommercialOutcomeDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug do payload de exportação (gerado, timestamp, decisão, CTA, prioridade).</summary>
        public bool ShowExportDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug da persistência local (snapshot salvo, timestamp, restaurado, sessão/proposta).</summary>
        public bool ShowPersistenceDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug do relatório final/handoff (gerado, timestamp, decisão e prioridade).</summary>
        public bool ShowHandoffDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug do resumo compartilhável (gerado, timestamp, decisão, próxima ação).</summary>
        public bool ShowShareableDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug do diagnóstico de qualidade (score, label, principal força/fraqueza).</summary>
        public bool ShowQualityDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug do plano de melhorias (existe, quantidade, prioritária, categoria).</summary>
        public bool ShowImprovementDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug do preset (actual, tipo, foco, duração).</summary>
        public bool ShowPresetDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug do onboarding (aberto, preset, proposta, pronto).</summary>
        public bool ShowOnboardingDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug do fluxo curto (modo, etapa, progresso, tempo).</summary>
        public bool ShowShortFlowDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug de comparação entre hotspots.</summary>
        public bool ShowComparisonDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug de contexto de hotspot (aberto/fechado, origem, premium).</summary>
        public bool ShowHotspotContextDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug de gaze-like (aiming mode, alvo de gaze, estabilidade, limiar).</summary>
        public bool ShowGazeLikeDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug de targeting (detectado, resolvido, score, stickiness).</summary>
        public bool ShowTargetingDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug de hover/dwell e confirmação.</summary>
        public bool ShowHoverDwellDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug de input (origem e último comando).</summary>
        public bool ShowInputDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug de runtime XR (modo, XR activo, fallback, init).</summary>
        public bool ShowXRDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug de input XR (disponível, activo, modo, última acção).</summary>
        public bool ShowXRInputDebugLine { get; set; } = true;

        /// <summary>Se true, mostra linha de debug de raycast XR (activo, último hit, distância, origem).</summary>
        public bool ShowXRRaycastDebugLine { get; set; } = true;

        public void Build(Transform parent, Font font)
        {
            _font = font;
            var go = new GameObject("QuestHUD");
            go.transform.SetParent(parent, false);
            var rt = go.AddComponent<RectTransform>();
            rt.anchorMin = new Vector2(0, 1);
            rt.anchorMax = new Vector2(1, 1);
            rt.pivot = new Vector2(0.5f, 1f);
            rt.offsetMin = new Vector2(16, -200);
            rt.offsetMax = new Vector2(-16, -16);
            var vlg = go.AddComponent<VerticalLayoutGroup>();
            vlg.spacing = 14;
            vlg.padding = new RectOffset(28, 20, 28, 20);
            vlg.childForceExpandHeight = false;

            _titleText = AddLabel(go.transform, "—", 26, font, true);

            var statusRow = new GameObject("StatusRow");
            statusRow.transform.SetParent(go.transform, false);
            statusRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 28);
            var statusVlg = statusRow.AddComponent<VerticalLayoutGroup>();
            statusVlg.spacing = 4;
            _statusText = AddLabel(statusRow.transform, "Modo: —  |  Pronto: —", 16, font, false);

            var readinessRow = new GameObject("ReadinessRow");
            readinessRow.transform.SetParent(go.transform, false);
            readinessRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 24);
            _readinessText = AddLabel(readinessRow.transform, ModoTesteQuest + "  |  Build: —  Dados: —  Nav: —", 14, font, false);

            var progressRow = new GameObject("ProgressRow");
            progressRow.transform.SetParent(go.transform, false);
            progressRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 32);
            _progressText = AddLabel(progressRow.transform, "—", 20, font, true);

            var focusRow = new GameObject("FocusRow");
            focusRow.transform.SetParent(go.transform, false);
            focusRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 22);
            _focusIndicatorText = AddLabel(focusRow.transform, "", 14, font, false);

            var selectionRow = new GameObject("SelectionRow");
            selectionRow.transform.SetParent(go.transform, false);
            selectionRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 20);
            _selectionIndicatorText = AddLabel(selectionRow.transform, "", 13, font, false);

            var pointedRow = new GameObject("PointedRow");
            pointedRow.transform.SetParent(go.transform, false);
            pointedRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 18);
            _pointedTargetText = AddLabel(pointedRow.transform, "", 12, font, false);

            var inputDebugRow = new GameObject("InputDebugRow");
            inputDebugRow.transform.SetParent(go.transform, false);
            inputDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 16);
            _inputDebugText = AddLabel(inputDebugRow.transform, "", 11, font, false);
            _inputDebugText.color = new Color(0.6f, 0.65f, 0.7f, 1f);

            var xrDebugRow = new GameObject("XRDebugRow");
            xrDebugRow.transform.SetParent(go.transform, false);
            xrDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 14);
            _xrDebugText = AddLabel(xrDebugRow.transform, "", 10, font, false);
            _xrDebugText.color = new Color(0.55f, 0.6f, 0.65f, 1f);

            var xrInputDebugRow = new GameObject("XRInputDebugRow");
            xrInputDebugRow.transform.SetParent(go.transform, false);
            xrInputDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
            _xrInputDebugText = AddLabel(xrInputDebugRow.transform, "", 10, font, false);
            _xrInputDebugText.color = new Color(0.5f, 0.55f, 0.6f, 1f);

            var xrRaycastDebugRow = new GameObject("XRRaycastDebugRow");
            xrRaycastDebugRow.transform.SetParent(go.transform, false);
            xrRaycastDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
            _xrRaycastDebugText = AddLabel(xrRaycastDebugRow.transform, "", 10, font, false);
            _xrRaycastDebugText.color = new Color(0.48f, 0.52f, 0.58f, 1f);

            var hoverDwellDebugRow = new GameObject("HoverDwellDebugRow");
            hoverDwellDebugRow.transform.SetParent(go.transform, false);
            hoverDwellDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
            _hoverDwellDebugText = AddLabel(hoverDwellDebugRow.transform, "", 10, font, false);
            _hoverDwellDebugText.color = new Color(0.45f, 0.5f, 0.55f, 1f);

            var targetingDebugRow = new GameObject("TargetingDebugRow");
            targetingDebugRow.transform.SetParent(go.transform, false);
            targetingDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
            _targetingDebugText = AddLabel(targetingDebugRow.transform, "", 10, font, false);
            _targetingDebugText.color = new Color(0.42f, 0.48f, 0.52f, 1f);

            var gazeLikeDebugRow = new GameObject("GazeLikeDebugRow");
            gazeLikeDebugRow.transform.SetParent(go.transform, false);
            gazeLikeDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
            _gazeLikeDebugText = AddLabel(gazeLikeDebugRow.transform, "", 10, font, false);
            _gazeLikeDebugText.color = new Color(0.4f, 0.46f, 0.5f, 1f);

            var hotspotContextDebugRow = new GameObject("HotspotContextDebugRow");
            hotspotContextDebugRow.transform.SetParent(go.transform, false);
            hotspotContextDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
            _hotspotContextDebugText = AddLabel(hotspotContextDebugRow.transform, "", 10, font, false);
            _hotspotContextDebugText.color = new Color(0.38f, 0.44f, 0.48f, 1f);

            var comparisonDebugRow = new GameObject("ComparisonDebugRow");
            comparisonDebugRow.transform.SetParent(go.transform, false);
            comparisonDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
            _comparisonDebugText = AddLabel(comparisonDebugRow.transform, "", 10, font, false);
            _comparisonDebugText.color = new Color(0.36f, 0.42f, 0.46f, 1f);

            var closingDebugRow = new GameObject("ClosingDebugRow");
            closingDebugRow.transform.SetParent(go.transform, false);
            closingDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
            _closingDebugText = AddLabel(closingDebugRow.transform, "", 10, font, false);
            _closingDebugText.color = new Color(0.34f, 0.5f, 0.42f, 1f);

            var commercialOutcomeDebugRow = new GameObject("CommercialOutcomeDebugRow");
            commercialOutcomeDebugRow.transform.SetParent(go.transform, false);
            commercialOutcomeDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
            _commercialOutcomeDebugText = AddLabel(commercialOutcomeDebugRow.transform, "", 10, font, false);
            _commercialOutcomeDebugText.color = new Color(0.32f, 0.48f, 0.4f, 1f);

            var exportDebugRow = new GameObject("ExportDebugRow");
            exportDebugRow.transform.SetParent(go.transform, false);
            exportDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
            _exportDebugText = AddLabel(exportDebugRow.transform, "", 10, font, false);
            _exportDebugText.color = new Color(0.3f, 0.46f, 0.5f, 1f);

            var persistenceDebugRow = new GameObject("PersistenceDebugRow");
            persistenceDebugRow.transform.SetParent(go.transform, false);
            persistenceDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
            _persistenceDebugText = AddLabel(persistenceDebugRow.transform, "", 10, font, false);
            _persistenceDebugText.color = new Color(0.28f, 0.44f, 0.48f, 1f);

            var handoffDebugRow = new GameObject("HandoffDebugRow");
            handoffDebugRow.transform.SetParent(go.transform, false);
            handoffDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
            _handoffDebugText = AddLabel(handoffDebugRow.transform, "", 10, font, false);
            _handoffDebugText.color = new Color(0.26f, 0.46f, 0.42f, 1f);

            var shareableDebugRow = new GameObject("ShareableDebugRow");
            shareableDebugRow.transform.SetParent(go.transform, false);
            shareableDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
            _shareableDebugText = AddLabel(shareableDebugRow.transform, "", 10, font, false);
            _shareableDebugText.color = new Color(0.24f, 0.44f, 0.46f, 1f);

            var qualityDebugRow = new GameObject("QualityDebugRow");
            qualityDebugRow.transform.SetParent(go.transform, false);
            qualityDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
            _qualityDebugText = AddLabel(qualityDebugRow.transform, "", 10, font, false);
            _qualityDebugText.color = new Color(0.28f, 0.42f, 0.48f, 1f);

            var improvementDebugRow = new GameObject("ImprovementDebugRow");
            improvementDebugRow.transform.SetParent(go.transform, false);
            improvementDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
            _improvementDebugText = AddLabel(improvementDebugRow.transform, "", 10, font, false);
            _improvementDebugText.color = new Color(0.32f, 0.4f, 0.46f, 1f);

            var presetDebugRow = new GameObject("PresetDebugRow");
            presetDebugRow.transform.SetParent(go.transform, false);
            presetDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
            _presetDebugText = AddLabel(presetDebugRow.transform, "", 10, font, false);
            _presetDebugText.color = new Color(0.3f, 0.46f, 0.4f, 1f);

            var onboardingDebugRow = new GameObject("OnboardingDebugRow");
            onboardingDebugRow.transform.SetParent(go.transform, false);
            onboardingDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
            _onboardingDebugText = AddLabel(onboardingDebugRow.transform, "", 10, font, false);
            _onboardingDebugText.color = new Color(0.36f, 0.44f, 0.5f, 1f);

            var shortFlowDebugRow = new GameObject("ShortFlowDebugRow");
            shortFlowDebugRow.transform.SetParent(go.transform, false);
            shortFlowDebugRow.AddComponent<RectTransform>().sizeDelta = new Vector2(0, 12);
            _shortFlowDebugText = AddLabel(shortFlowDebugRow.transform, "", 10, font, false);
            _shortFlowDebugText.color = new Color(0.5f, 0.55f, 0.7f, 1f);

            var blockGo = new GameObject("CurrentBlock");
            blockGo.transform.SetParent(go.transform, false);
            blockGo.AddComponent<LayoutElement>().preferredHeight = 72;
            _blockHighlight = blockGo.AddComponent<Image>();
            _blockHighlight.color = new Color(0.2f, 0.28f, 0.38f, 0.85f);
            var blockVlg = blockGo.AddComponent<VerticalLayoutGroup>();
            blockVlg.spacing = 6;
            blockVlg.padding = new RectOffset(20, 14, 20, 14);
            _blockLabelText = AddLabel(blockGo.transform, "Passo atual", 18, font, true);
            _blockContentText = AddLabel(blockGo.transform, "—", 16, font, false);
        }

        public void Refresh(QuestPresentationSession session, QuestSelectionController selectionController, QuestShortFlowState shortFlowState = null, QuestPointerPreparationController pointerPrepController = null, QuestSimulatedPointerController simulatedPointerController = null, IQuestPresentationInputDispatcher inputDispatcher = null, QuestHoverDwellController hoverDwellController = null, QuestTargetResolverController targetResolverController = null, QuestGazeLikeController gazeLikeController = null)
        {
            if (session?.MRPlan == null)
            {
                _titleText.text = "—";
                _statusText.text = "Modo: —  |  Pronto: Não";
                _progressText.text = "—";
                _blockLabelText.text = "—";
                _blockContentText.text = "—";
                RefreshReadinessLine(session?.RuntimeReadiness);
                RefreshFocusLine(null);
                RefreshSelectionLine(null);
                RefreshPointedLine(null, null);
                RefreshInputDebugLine(null);
                RefreshXRDebugLine(null);
                RefreshXRInputLine(null);
                RefreshXRRaycastLine(null, null);
                RefreshHoverDwellLine(null, null);
                RefreshTargetingLine(null, null);
                RefreshGazeLikeLine(null);
                RefreshHotspotContextLine(null);
                RefreshComparisonLine(null);
                RefreshClosingLine(null);
                RefreshCommercialOutcomeLine(null);
                RefreshExportLine(null);
                RefreshPersistenceLine(null);
                RefreshHandoffLine(null);
                RefreshShareableLine(null);
                RefreshQualityLine(null);
                RefreshImprovementLine(null);
                RefreshPresetLine(null);
                RefreshOnboardingLine(null);
                RefreshShortFlowLine(null);
                return;
            }

            _titleText.text = string.IsNullOrEmpty(session.MRPlan.PresentationTitle) ? "Apresentação Quest" : session.MRPlan.PresentationTitle;
            _statusText.text = "Modo: " + NavigationModeLabel(session.NavigationMode) + "  |  Pronto: " + (session.IsPresentationReady ? "Sim" : "Não");
            RefreshReadinessLine(session.RuntimeReadiness);

            var total = session.TotalSteps;
            var current = session.CurrentGuidedStepIndex + 1;
            _progressText.text = total > 0 ? $"{current} / {total}" : "—";

            if (session.CurrentStep != null)
            {
                _blockLabelText.text = "Passo atual";
                _blockContentText.text = session.CurrentStep.Title ?? session.CurrentStep.Description ?? "—";
                _blockHighlight.color = new Color(0.18f, 0.35f, 0.5f, 0.9f);
            }
            else if (session.CurrentHotspot != null)
            {
                _blockLabelText.text = "Hotspot";
                _blockContentText.text = session.CurrentHotspot.Title ?? session.CurrentHotspot.Description ?? "—";
                _blockHighlight.color = new Color(0.35f, 0.28f, 0.45f, 0.9f);
            }
            else if (session.CurrentSceneState != null)
            {
                _blockLabelText.text = "Estado da cena";
                _blockContentText.text = session.CurrentSceneState.Name ?? session.CurrentSceneState.Description ?? "—";
                _blockHighlight.color = new Color(0.28f, 0.4f, 0.35f, 0.9f);
            }
            else
            {
                _blockLabelText.text = "Apresentação";
                _blockContentText.text = total > 0 ? "Use os botões para navegar." : "Nenhum passo disponível.";
                _blockHighlight.color = new Color(0.2f, 0.28f, 0.38f, 0.85f);
            }

            RefreshFocusLine(session);
            RefreshSelectionLine(selectionController);
            RefreshPointedLine(pointerPrepController, simulatedPointerController);
            RefreshInputDebugLine(inputDispatcher);
            RefreshXRDebugLine(session);
            RefreshXRInputLine(session);
            RefreshXRRaycastLine(session, pointerPrepController);
            RefreshHoverDwellLine(session, hoverDwellController);
            RefreshTargetingLine(session, targetResolverController);
            RefreshGazeLikeLine(session);
            RefreshHotspotContextLine(session);
            RefreshComparisonLine(session);
            RefreshClosingLine(session);
            RefreshCommercialOutcomeLine(session);
            RefreshExportLine(session);
            RefreshPersistenceLine(session);
            RefreshHandoffLine(session);
            RefreshShareableLine(session);
            RefreshQualityLine(session);
            RefreshImprovementLine(session);
            RefreshPresetLine(session);
            RefreshOnboardingLine(session);
            RefreshShortFlowLine(shortFlowState);
        }

        private void RefreshShortFlowLine(QuestShortFlowState state)
        {
            if (_shortFlowDebugText == null) return;
            if (!ShowShortFlowDebugLine || state == null)
            {
                _shortFlowDebugText.text = "";
                return;
            }
            var mode = state.FlowMode.ToString();
            var stage = state.CurrentCoreStage.ToString();
            var total = state.TotalCoreStages > 0 ? state.TotalCoreStages : 5;
            var idx = (int)state.CurrentCoreStage + 1;
            var ready = state.IsReadyForClosing ? "Sim" : "Não";
            _shortFlowDebugText.text = $"Fluxo curto: {mode}  |  Etapa {idx}/{total} ({stage})  |  Restante ~{state.EstimatedRemainingMinutes} min  |  Pronto p/ closing: {ready}";
        }

        private void RefreshClosingLine(QuestPresentationSession session)
        {
            if (_closingDebugText == null) return;
            if (!ShowClosingDebugLine || session == null)
            {
                _closingDebugText.text = "";
                return;
            }
            var closing = session.CurrentClosingState;
            if (closing == null || !closing.IsClosingOpen)
            {
                _closingDebugText.text = "Fechamento: Fechado";
                return;
            }
            var openClosed = "Aberto";
            var cta = closing.PrimaryCTA ?? "—";
            var propId = closing.RecommendedProposalId ?? "—";
            var ready = closing.IsReadyToClose ? "Sim" : "Não";
            var lastAction = session.LastClosingAction ?? "—";
            _closingDebugText.text = "Fechamento: " + openClosed + "  |  CTA " + cta + "  |  proposta " + propId + "  |  pronto " + ready + "  |  última " + lastAction;
        }

        private void RefreshCommercialOutcomeLine(QuestPresentationSession session)
        {
            if (_commercialOutcomeDebugText == null) return;
            if (!ShowCommercialOutcomeDebugLine || session == null)
            {
                _commercialOutcomeDebugText.text = "";
                return;
            }
            var outcome = session.CurrentCommercialOutcome;
            var state = session.LastDecisionState;
            var cta = session.LastConfirmedCTA ?? "—";
            var propId = outcome?.SelectedProposalId ?? session.Proposal?.Id ?? "—";
            var priority = outcome != null ? outcome.FollowUpPriority.ToString() : "—";
            _commercialOutcomeDebugText.text = "Comercial: estado " + state + "  |  CTA " + cta + "  |  proposta " + propId + "  |  prioridade " + priority;
        }

        private void RefreshExportLine(QuestPresentationSession session)
        {
            if (_exportDebugText == null) return;
            if (!ShowExportDebugLine || session == null)
            {
                _exportDebugText.text = "";
                return;
            }
            var payload = session.CurrentExportPayload;
            var hasPayload = payload != null;
            var ts = session.LastExportTimestamp;
            var tsStr = ts.HasValue ? ts.Value.ToString("HH:mm:ss") : "—";
            var decision = payload?.FinalDecisionState.ToString() ?? "—";
            var cta = payload?.ConfirmedCTA ?? "—";
            var priority = payload != null ? payload.FollowUpPriority.ToString() : "—";
            _exportDebugText.text = "Export: " + (hasPayload ? "Sim" : "Não") + "  |  " + tsStr + "  |  decisão " + decision + "  |  CTA " + cta + "  |  prior. " + priority;
        }

        private void RefreshPersistenceLine(QuestPresentationSession session)
        {
            if (_persistenceDebugText == null) return;
            if (!ShowPersistenceDebugLine || session == null)
            {
                _persistenceDebugText.text = "";
                return;
            }
            var snap = session.CurrentLocalSnapshot;
            var hasSaved = snap != null;
            var savedAt = snap?.SavedAt ?? "—";
            var restored = session.LastRestoreTimestamp.HasValue ? "Sim" : "Não";
            var sessionId = snap?.SessionId ?? "—";
            var proposalId = snap?.ActiveProposalId ?? "—";
            _persistenceDebugText.text = "Snapshot: " + (hasSaved ? "Sim" : "Não") + "  |  " + savedAt + "  |  restaurado " + restored + "  |  sessão " + sessionId + "  |  proposta " + proposalId;
        }

        private void RefreshHandoffLine(QuestPresentationSession session)
        {
            if (_handoffDebugText == null) return;
            if (!ShowHandoffDebugLine || session == null)
            {
                _handoffDebugText.text = "";
                return;
            }
            var report = session.CurrentHandoffReport;
            var hasReport = report != null;
            var ts = session.LastHandoffGeneratedAt.HasValue ? session.LastHandoffGeneratedAt.Value.ToString("HH:mm:ss") : "—";
            var decision = hasReport ? report.FinalDecisionState.ToString() : session.LastDecisionState.ToString();
            var priority = hasReport ? report.FollowUpPriority.ToString() : (session.CurrentCommercialOutcome != null ? session.CurrentCommercialOutcome.FollowUpPriority.ToString() : "—");
            _handoffDebugText.text = "Handoff: " + (hasReport ? "Sim" : "Não") + "  |  " + ts + "  |  decisão " + decision + "  |  prior. " + priority;
        }

        private void RefreshShareableLine(QuestPresentationSession session)
        {
            if (_shareableDebugText == null) return;
            if (!ShowShareableDebugLine || session == null)
            {
                _shareableDebugText.text = "";
                return;
            }
            var summary = session.CurrentShareableSummary;
            var hasSummary = summary != null;
            var ts = session.LastShareableSummaryGeneratedAt.HasValue ? session.LastShareableSummaryGeneratedAt.Value.ToString("HH:mm:ss") : "—";
            var decision = hasSummary ? (summary.FinalDecisionLabel ?? "—") : (session.CurrentHandoffReport?.FinalDecisionState.ToString() ?? session.LastDecisionState.ToString());
            var nextAction = hasSummary ? (summary.SuggestedNextActionLabel ?? "—") : (session.CurrentHandoffReport?.SuggestedNextAction ?? session.CurrentExportPayload?.SuggestedNextAction ?? "—");
            _shareableDebugText.text = "Resumo: " + (hasSummary ? "Sim" : "Não") + "  |  " + ts + "  |  decisão " + decision + "  |  próxima " + nextAction;
        }

        private void RefreshQualityLine(QuestPresentationSession session)
        {
            if (_qualityDebugText == null) return;
            if (!ShowQualityDebugLine || session == null)
            {
                _qualityDebugText.text = "";
                return;
            }
            var assessment = session.CurrentQualityAssessment;
            var hasAssessment = assessment != null;
            var ts = session.LastQualityAssessmentGeneratedAt.HasValue ? session.LastQualityAssessmentGeneratedAt.Value.ToString("HH:mm:ss") : "—";
            var overallScore = hasAssessment ? ((assessment.PresentationQualityScore + assessment.CommercialClarityScore + assessment.InteractionQualityScore + assessment.DecisionReadinessScore + assessment.EngagementContributionScore) / 5).ToString() : "—";
            var score = hasAssessment ? overallScore : "—";
            var label = hasAssessment ? (assessment.QualityLabel ?? "—") : "—";
            var mainStrength = hasAssessment && assessment.Strengths != null && assessment.Strengths.Count > 0 ? assessment.Strengths[0] : "—";
            var mainWeakness = hasAssessment && assessment.Weaknesses != null && assessment.Weaknesses.Count > 0 ? assessment.Weaknesses[0] : "—";
            _qualityDebugText.text = "Qualidade: " + (hasAssessment ? "Sim" : "Não") + "  |  " + ts + "  |  score " + score + "  |  label " + label + "  |  força " + (mainStrength.Length > 20 ? mainStrength.Substring(0, 20) + "…" : mainStrength) + "  |  fraqueza " + (mainWeakness.Length > 20 ? mainWeakness.Substring(0, 20) + "…" : mainWeakness);
        }

        private void RefreshImprovementLine(QuestPresentationSession session)
        {
            if (_improvementDebugText == null) return;
            if (!ShowImprovementDebugLine || session == null)
            {
                _improvementDebugText.text = "";
                return;
            }
            var plan = session.CurrentImprovementPlan;
            var hasPlan = plan != null;
            var count = hasPlan && plan.Recommendations != null ? plan.Recommendations.Count : 0;
            var top = plan?.TopPriorityRecommendation;
            var topTitle = top != null ? (top.Title ?? top.Summary ?? "—") : "—";
            var topCategory = top != null ? (top.Category ?? "—") : "—";
            if (topTitle.Length > 25) topTitle = topTitle.Substring(0, 25) + "…";
            _improvementDebugText.text = "Melhorias: " + (hasPlan ? "Sim" : "Não") + "  |  " + count + " rec.  |  prioritária " + topTitle + "  |  categoria " + topCategory;
        }

        private void RefreshPresetLine(QuestPresentationSession session)
        {
            if (_presetDebugText == null) return;
            if (!ShowPresetDebugLine || session == null)
            {
                _presetDebugText.text = "";
                return;
            }
            var preset = session.CurrentPresentationPreset;
            if (preset == null)
            {
                _presetDebugText.text = "Preset: Nenhum  |  tipo —  |  foco —  |  duração —";
                return;
            }
            var typeLabel = preset.PresetType.ToString();
            var focusParts = new System.Collections.Generic.List<string>();
            if (preset.EmphasizeHotspots) focusParts.Add("Hotspots");
            if (preset.EmphasizeComparison) focusParts.Add("Comparação");
            if (preset.EmphasizeClosing) focusParts.Add("Fechamento");
            var focus = focusParts.Count > 0 ? string.Join(", ", focusParts) : "Roteiro";
            var duration = preset.EstimatedDurationMinutes > 0 ? preset.EstimatedDurationMinutes + " min" : "—";
            _presetDebugText.text = "Preset: " + (preset.Name ?? preset.PresetId ?? "—") + "  |  tipo " + typeLabel + "  |  foco " + focus + "  |  duração " + duration;
        }

        private void RefreshOnboardingLine(QuestPresentationSession session)
        {
            if (_onboardingDebugText == null) return;
            if (!ShowOnboardingDebugLine || session == null)
            {
                _onboardingDebugText.text = "";
                return;
            }
            var state = session.CurrentOnboardingState;
            var isOpen = state != null && state.IsOnboardingOpen;
            var presetLabel = state?.PresetLabel ?? (session.CurrentPresentationPreset?.Name ?? session.CurrentPresentationPreset?.PresetId ?? "—");
            var proposalLabel = state?.ProposalLabel ?? (session.Proposal?.Name ?? session.Proposal?.Id ?? "—");
            var ready = state?.IsReadyToStart ?? (session.MRPlan != null);
            if (proposalLabel.Length > 18) proposalLabel = proposalLabel.Substring(0, 18) + "…";
            _onboardingDebugText.text = "Onboarding: " + (isOpen ? "Aberto" : "Fechado") + "  |  preset " + presetLabel + "  |  proposta " + proposalLabel + "  |  pronto " + (ready ? "Sim" : "Não");
        }

        private void RefreshComparisonLine(QuestPresentationSession session)
        {
            if (_comparisonDebugText == null) return;
            if (!ShowComparisonDebugLine || session == null)
            {
                _comparisonDebugText.text = "";
                return;
            }
            var comp = session.CurrentHotspotComparison;
            if (comp == null || !comp.IsComparisonOpen)
            {
                _comparisonDebugText.text = "Comparação: Fechada";
                return;
            }
            var leftLabel = comp.LeftTitle ?? comp.LeftHotspotId ?? "—";
            var rightLabel = comp.RightTitle ?? comp.RightHotspotId ?? "—";
            var expSide = string.IsNullOrEmpty(comp.BetterForExperience) ? "—" : (comp.BetterForExperience == "Left" ? "Esq." : "Dir.");
            var upsellSide = string.IsNullOrEmpty(comp.BetterForUpsell) ? "—" : (comp.BetterForUpsell == "Left" ? "Esq." : "Dir.");
            var claritySide = string.IsNullOrEmpty(comp.BetterForClarity) ? "—" : (comp.BetterForClarity == "Left" ? "Esq." : "Dir.");
            var origin = comp.OpenedBySource ?? "—";
            _comparisonDebugText.text = "Comparação: Activa  |  Esq. " + leftLabel + "  |  Dir. " + rightLabel + "  |  melhor exp. " + expSide + "  |  upsell " + upsellSide + "  |  claro " + claritySide + "  |  origem " + origin;
        }

        private void RefreshPointedLine(QuestPointerPreparationController pointerPrepController, QuestSimulatedPointerController simulatedPointerController)
        {
            if (_pointedTargetText == null) return;
            var modeLabel = PointerSourceModeLabel(simulatedPointerController?.CurrentSourceMode ?? Core.QuestPointerSourceMode.CenterScreenSimulated);
            var pointed = pointerPrepController?.GetPointedTarget();
            if (pointed == null)
            {
                _pointedTargetText.text = "Alvo apontado: —  |  Modo: " + modeLabel + "  (P = alternar, Enter = confirmar)";
                return;
            }
            var interactable = pointed.IsInteractable ? "Sim" : "Não";
            _pointedTargetText.text = "Alvo apontado: " + pointed.HoverHint + "  |  Modo: " + modeLabel + "  |  Interagível: " + interactable + "  |  Ação: " + pointed.SelectionHint + "  (P = alternar)";
        }

        private void RefreshInputDebugLine(IQuestPresentationInputDispatcher inputDispatcher)
        {
            if (_inputDebugText == null) return;
            if (!ShowInputDebugLine || inputDispatcher == null)
            {
                _inputDebugText.text = "";
                return;
            }
            var sourceLabel = InputSourceLabel(inputDispatcher.CurrentSource);
            var lastCommands = inputDispatcher.GetLastCommands(1);
            var lastLabel = lastCommands.Count > 0 ? CommandTypeLabel(lastCommands[0].CommandType) : "—";
            _inputDebugText.text = "Input: " + sourceLabel + "  |  Último: " + lastLabel;
        }

        private void RefreshXRDebugLine(QuestPresentationSession session)
        {
            if (_xrDebugText == null) return;
            if (!ShowXRDebugLine || session == null)
            {
                _xrDebugText.text = "";
                return;
            }
            var modeLabel = RuntimeModeLabel(session.RuntimeMode);
            var xrLabel = session.IsXRActive ? "Sim" : "Não";
            var fallbackLabel = session.IsFallbackActive ? "Sim" : "Não";
            var initLabel = string.IsNullOrEmpty(session.XRInitStatus) ? "—" : session.XRInitStatus;
            _xrDebugText.text = "Runtime: " + modeLabel + "  |  XR: " + xrLabel + "  |  Fallback: " + fallbackLabel + "  |  Init: " + initLabel;
        }

        private static string RuntimeModeLabel(QuestPresentationRuntimeMode mode)
        {
            switch (mode)
            {
                case QuestPresentationRuntimeMode.EditorFallback: return "EditorFallback";
                case QuestPresentationRuntimeMode.SimulatedXR: return "SimulatedXR";
                case QuestPresentationRuntimeMode.RealXR: return "RealXR";
                default: return "—";
            }
        }

        private void RefreshXRInputLine(QuestPresentationSession session)
        {
            if (_xrInputDebugText == null) return;
            if (!ShowXRInputDebugLine || session?.XRInputStatus == null)
            {
                _xrInputDebugText.text = "";
                return;
            }
            var s = session.XRInputStatus;
            var avail = s.IsXRInputAvailable ? "Sim" : "Não";
            var active = s.IsXRInputEnabled ? "Sim" : "Não";
            var fallbackOnly = s.IsBridgeInFallbackOnly ? "Sim" : "Não";
            var modeLabel = XRInputModeLabel(s.ActiveXRInputMode);
            var lastLabel = s.LastXRAction.HasValue ? CommandTypeLabel(s.LastXRAction.Value) : "—";
            _xrInputDebugText.text = "XR Input: disponível " + avail + "  |  activo " + active + "  |  fallback only " + fallbackOnly + "  |  modo " + modeLabel + "  |  última " + lastLabel;
        }

        private static string XRInputModeLabel(QuestXRInputMode mode)
        {
            switch (mode)
            {
                case QuestXRInputMode.None: return "None";
                case QuestXRInputMode.RuntimeFallback: return "RuntimeFallback";
                case QuestXRInputMode.XRControllerPrimary: return "XRControllerPrimary";
                case QuestXRInputMode.XRControllerSecondary: return "XRControllerSecondary";
                case QuestXRInputMode.FutureHandTracking: return "FutureHandTracking";
                case QuestXRInputMode.FutureGaze: return "FutureGaze";
                default: return "—";
            }
        }

        private static string InputSourceLabel(QuestPresentationInputSourceType source)
        {
            switch (source)
            {
                case QuestPresentationInputSourceType.KeyboardFallback: return "KeyboardFallback";
                case QuestPresentationInputSourceType.EditorTest: return "EditorTest";
                case QuestPresentationInputSourceType.SimulatedHeadset: return "SimulatedHeadset";
                case QuestPresentationInputSourceType.FutureController: return "FutureController";
                case QuestPresentationInputSourceType.FutureHandTracking: return "FutureHandTracking";
                case QuestPresentationInputSourceType.FutureGaze: return "FutureGaze";
                default: return "—";
            }
        }

        private static string CommandTypeLabel(QuestPresentationInputCommandType type)
        {
            switch (type)
            {
                case QuestPresentationInputCommandType.NextFocus: return "NextFocus";
                case QuestPresentationInputCommandType.PreviousFocus: return "PreviousFocus";
                case QuestPresentationInputCommandType.ActivateFocus: return "ActivateFocus";
                case QuestPresentationInputCommandType.ExitFocusMode: return "ExitFocusMode";
                case QuestPresentationInputCommandType.NextSelectable: return "NextSelectable";
                case QuestPresentationInputCommandType.PreviousSelectable: return "PreviousSelectable";
                case QuestPresentationInputCommandType.ConfirmSelection: return "ConfirmSelection";
                case QuestPresentationInputCommandType.CancelSelection: return "CancelSelection";
                case QuestPresentationInputCommandType.TogglePointerMode: return "TogglePointerMode";
                case QuestPresentationInputCommandType.ConfirmPointedTarget: return "ConfirmPointedTarget";
                case QuestPresentationInputCommandType.NextStep: return "NextStep";
                case QuestPresentationInputCommandType.PreviousStep: return "PreviousStep";
                case QuestPresentationInputCommandType.NextHotspot: return "NextHotspot";
                case QuestPresentationInputCommandType.PreviousHotspot: return "PreviousHotspot";
                case QuestPresentationInputCommandType.NextSceneState: return "NextSceneState";
                case QuestPresentationInputCommandType.PreviousSceneState: return "PreviousSceneState";
                case QuestPresentationInputCommandType.ToggleNavigationMode: return "ToggleNavigationMode";
                case QuestPresentationInputCommandType.RestartPresentation: return "RestartPresentation";
                default: return "—";
            }
        }

        private static string PointerSourceModeLabel(Core.QuestPointerSourceMode mode)
        {
            switch (mode)
            {
                case Core.QuestPointerSourceMode.FocusDriven: return "FocusDriven";
                case Core.QuestPointerSourceMode.CenterScreenSimulated: return "CenterScreenSimulated";
                case Core.QuestPointerSourceMode.ManualCycleAssisted: return "ManualCycleAssisted";
                default: return "—";
            }
        }

        private void RefreshFocusLine(QuestPresentationSession session)
        {
            if (_focusIndicatorText == null) return;
            if (session == null || !session.IsInteractionModeActive)
            {
                _focusIndicatorText.text = "Modo interação: Não  (Tab = foco)";
                return;
            }
            var targetName = FocusTargetLabel(session.FocusedTargetType);
            var actionHint = FocusActionHint(session.FocusedTargetType);
            _focusIndicatorText.text = "Foco: " + targetName + "  |  Modo interação: Sim  |  Ação: " + actionHint;
        }

        private void RefreshSelectionLine(QuestSelectionController selectionController)
        {
            if (_selectionIndicatorText == null) return;
            var target = selectionController?.GetSelectedTarget();
            if (target == null)
            {
                _selectionIndicatorText.text = "Seleção: —  (F/G = alvos, Enter = ativar, Backspace = cancelar)";
                return;
            }
            _selectionIndicatorText.text = "Selecionado: " + target.DisplayName + "  |  Ação: " + target.SelectionHint + "  |  Enter = confirmar";
        }

        private static string FocusTargetLabel(QuestPresentationFocusTargetType type)
        {
            switch (type)
            {
                case QuestPresentationFocusTargetType.GuidedStepPanel: return "Passo";
                case QuestPresentationFocusTargetType.HotspotPanel: return "Hotspot";
                case QuestPresentationFocusTargetType.SceneStatePanel: return "Estado cena";
                case QuestPresentationFocusTargetType.ProgressPanel: return "Progresso";
                case QuestPresentationFocusTargetType.ActionPanel: return "Ações";
                default: return "—";
            }
        }

        private static string FocusActionHint(QuestPresentationFocusTargetType type)
        {
            switch (type)
            {
                case QuestPresentationFocusTargetType.GuidedStepPanel: return "Espaço = Próx. passo";
                case QuestPresentationFocusTargetType.HotspotPanel: return "Espaço = Próx. hotspot";
                case QuestPresentationFocusTargetType.SceneStatePanel: return "Espaço = Próx. estado";
                case QuestPresentationFocusTargetType.ProgressPanel: return "Espaço = Reiniciar";
                case QuestPresentationFocusTargetType.ActionPanel: return "Espaço = Alternar modo";
                default: return "—";
            }
        }

        private void RefreshReadinessLine(QuestRuntimeReadinessStatus readiness)
        {
            if (_readinessText == null) return;
            if (readiness == null)
            {
                _readinessText.text = ModoTesteQuest + "  |  Build: —  Dados: —  Nav: —";
                return;
            }
            _readinessText.text = ModoTesteQuest + "  |  Build: " + (readiness.IsBuildReady ? "Sim" : "Não")
                + "  Dados: " + (readiness.HasPresentationData ? "Sim" : "Não")
                + "  Nav: " + (readiness.HasNavigationControls ? "Sim" : "Não");
        }

        private void RefreshXRRaycastLine(QuestPresentationSession session, QuestPointerPreparationController pointerPrepController)
        {
            if (_xrRaycastDebugText == null) return;
            if (!ShowXRRaycastDebugLine || session == null)
            {
                _xrRaycastDebugText.text = "";
                return;
            }
            var active = session.XRRaycastActive ? "Sim" : "Não";
            var lastHit = session.LastXRRaycastHit;
            var hitId = lastHit != null && lastHit.IsValidTarget ? lastHit.HitTargetId : "—";
            var dist = lastHit != null && lastHit.IsValidTarget ? lastHit.HitDistance.ToString("F2") + " m" : "—";
            var origem = (pointerPrepController != null && pointerPrepController.IsPointedFromXRRaycast) ? "XR real" : "Fallback";
            _xrRaycastDebugText.text = "Raycast XR: activo " + active + "  |  último hit " + hitId + "  |  dist " + dist + "  |  origem " + origem;
        }

        private void RefreshHoverDwellLine(QuestPresentationSession session, QuestHoverDwellController hoverDwellController)
        {
            if (_hoverDwellDebugText == null) return;
            if (!ShowHoverDwellDebugLine || session == null)
            {
                _hoverDwellDebugText.text = "";
                return;
            }
            var modeLabel = ConfirmationModeLabel(session.ConfirmationMode);
            var hover = session.CurrentHoverState;
            var hoverId = hover != null ? hover.TargetId : "—";
            var dwellSec = hover != null ? hover.HoverElapsedSeconds.ToString("F1") + " s" : "—";
            var ready = (hover != null && hover.IsDwellReady) ? "Sim" : "Não";
            var lastConfirm = string.IsNullOrEmpty(session.LastConfirmationTargetId) ? "—" : session.LastConfirmationTargetId;
            _hoverDwellDebugText.text = "Hover: " + hoverId + "  |  dwell " + dwellSec + "  |  pronto " + ready + "  |  modo " + modeLabel + "  |  última conf. " + lastConfirm;
        }

        private static string ConfirmationModeLabel(QuestTargetConfirmationMode mode)
        {
            switch (mode)
            {
                case QuestTargetConfirmationMode.ExplicitOnly: return "Explícita";
                case QuestTargetConfirmationMode.DwellOnly: return "Dwell";
                case QuestTargetConfirmationMode.DwellOrExplicit: return "Dwell+Explícita";
                default: return "—";
            }
        }

        private void RefreshTargetingLine(QuestPresentationSession session, QuestTargetResolverController targetResolverController)
        {
            if (_targetingDebugText == null) return;
            if (!ShowTargetingDebugLine || session == null)
            {
                _targetingDebugText.text = "";
                return;
            }
            var detected = string.IsNullOrEmpty(session.DetectedTargetId) ? "—" : session.DetectedTargetId;
            var resolved = string.IsNullOrEmpty(session.ResolvedTargetId) ? "—" : session.ResolvedTargetId;
            var modeLabel = TargetSourceModeLabel(session.ResolvedTargetSourceMode);
            var stick = session.StickinessAppliedLastFrame ? "Sim" : "Não";
            var score = targetResolverController?.ResolvedCandidate != null
                ? targetResolverController.ResolvedCandidate.PriorityScore.ToString("F1")
                : "—";
            _targetingDebugText.text = "Detectado: " + detected + "  |  Resolvido: " + resolved + "  |  prior. " + score + "  |  origem " + modeLabel + "  |  stick " + stick;
        }

        private static string TargetSourceModeLabel(QuestTargetSourceMode mode)
        {
            switch (mode)
            {
                case QuestTargetSourceMode.FocusFallback: return "FocusFallback";
                case QuestTargetSourceMode.SimulatedPointer: return "SimulatedPointer";
                case QuestTargetSourceMode.XRRaycast: return "XRRaycast";
                case QuestTargetSourceMode.FutureGaze: return "FutureGaze";
                default: return "—";
            }
        }

        private void RefreshGazeLikeLine(QuestPresentationSession session)
        {
            if (_gazeLikeDebugText == null) return;
            if (!ShowGazeLikeDebugLine || session == null)
            {
                _gazeLikeDebugText.text = "";
                return;
            }
            var modeLabel = AimingModeLabel(session.AimingMode);
            var fromGaze = session.CurrentTargetFromGazeLike ? "Sim" : "Não";
            var gaze = session.GazeLikeState;
            var stabilitySec = gaze != null ? gaze.StabilityElapsedSeconds.ToString("F2") + " s" : "—";
            var stableEnough = (gaze != null && gaze.IsStableEnough) ? "Sim" : "Não";
            var gazeTarget = gaze != null && !string.IsNullOrEmpty(gaze.CurrentGazeTargetId) ? gaze.CurrentGazeTargetId : "—";
            _gazeLikeDebugText.text = "Aiming: " + modeLabel + "  |  alvo gaze " + gazeTarget + "  |  estab. " + stabilitySec + "  |  estável " + stableEnough + "  |  origem gaze-like " + fromGaze;
        }

        private static string AimingModeLabel(QuestAimingMode mode)
        {
            switch (mode)
            {
                case QuestAimingMode.FallbackOnly: return "FallbackOnly";
                case QuestAimingMode.XRRaycastPreferred: return "XRRaycastPreferred";
                case QuestAimingMode.GazeLikePreferred: return "GazeLikePreferred";
                case QuestAimingMode.Hybrid: return "Hybrid";
                default: return "—";
            }
        }

        private void RefreshHotspotContextLine(QuestPresentationSession session)
        {
            if (_hotspotContextDebugText == null) return;
            if (!ShowHotspotContextDebugLine || session == null)
            {
                _hotspotContextDebugText.text = "";
                return;
            }
            var ctx = session.CurrentHotspotContext;
            var hotspotLabel = ctx != null && ctx.IsContextOpen ? (ctx.ContextTitle ?? ctx.HotspotId ?? "—") : "—";
            var openClosed = session.HasHotspotContextOpen ? "Aberto" : "Fechado";
            var source = ctx != null ? (ctx.OpenedBySource ?? "—") : "—";
            var premium = (ctx != null && ctx.IsPremiumUpsell) ? "Sim" : "Não";
            var narrativeActive = (ctx != null && ctx.IsStoryActive) ? "Sim" : "Não";
            var stepInfo = ctx != null && ctx.IsStoryActive && ctx.StorySteps != null && ctx.StorySteps.Count > 0
                ? (ctx.CurrentStoryStepIndex + 1) + "/" + ctx.StorySteps.Count
                : "—";
            var stepUpsell = (ctx?.CurrentStoryStep != null && ctx.CurrentStoryStep.IsUpsellMoment) ? "Sim" : "Não";
            _hotspotContextDebugText.text = "Contexto hotspot: " + hotspotLabel + "  |  " + openClosed + "  |  origem " + source + "  |  premium " + premium + "  |  narrativa " + narrativeActive + "  |  passo " + stepInfo + "  |  upsell passo " + stepUpsell;
        }

        private static string NavigationModeLabel(QuestPresentationNavigationMode mode)
        {
            switch (mode)
            {
                case QuestPresentationNavigationMode.Guided: return ModoGuiado;
                case QuestPresentationNavigationMode.Manual: return ModoManual;
                case QuestPresentationNavigationMode.FocusedHotspot: return ModoHotspot;
                default: return "—";
            }
        }

        private static Text AddLabel(Transform parent, string text, int fontSize, Font font, bool bold)
        {
            var go = new GameObject("Label");
            go.transform.SetParent(parent, false);
            go.AddComponent<RectTransform>().sizeDelta = new Vector2(0, fontSize + 10);
            var t = go.AddComponent<Text>();
            t.text = text;
            t.font = font;
            t.fontSize = fontSize;
            t.fontStyle = bold ? FontStyle.Bold : FontStyle.Normal;
            return t;
        }
    }
}
