using System;
using System.Collections.Generic;
using System.Linq;
using EventsAppQuest.Core;
using EventsAppQuest.Domain.Enums;
using EventsAppQuest.Domain.Models;
using UnityEngine;

namespace EventsAppQuest.Presentation
{
    /// <summary>
    /// Organizador do fluxo curto (5–10 minutos) para venda assistida.
    /// Não substitui a navegação/hotspots/comparação/closing; apenas orquestra uma jornada enxuta.
    /// </summary>
    public class QuestShortFlowController : MonoBehaviour
    {
        private const int DefaultImpactHotspotsCount = 3;

        private QuestPresentationSession _session;
        private QuestPresentationNavigationController _nav;
        private QuestPresentationOnboardingController _onboarding;
        private QuestHotspotContextController _hotspotContext;
        private QuestHotspotStoryController _hotspotStory;
        private QuestHotspotComparisonController _comparison;
        private QuestClosingExperienceController _closing;
        private QuestPresentationPresetController _presets;

        public QuestShortFlowState Current { get; private set; }

        public void Bind(QuestPresentationSession session,
            QuestPresentationNavigationController nav,
            QuestPresentationOnboardingController onboarding,
            QuestHotspotContextController hotspotContext,
            QuestHotspotStoryController hotspotStory,
            QuestHotspotComparisonController comparison,
            QuestClosingExperienceController closing,
            QuestPresentationPresetController presets)
        {
            _session = session;
            _nav = nav;
            _onboarding = onboarding;
            _hotspotContext = hotspotContext;
            _hotspotStory = hotspotStory;
            _comparison = comparison;
            _closing = closing;
            _presets = presets;

            if (Current == null)
                Current = BuildInitialState();

            RefreshState();
        }

        public void ToggleFlowMode()
        {
            if (Current == null) return;
            if (Current.FlowMode == QuestPresentationFlowMode.FullExperience)
                StartShortFlow(QuestPresentationFlowMode.GuidedSalesShort, true);
            else
                SetFullExperience();
        }

        public void StartShortFlow(QuestPresentationFlowMode mode, bool isSellerGuided)
        {
            if (_session == null) return;
            if (Current == null) Current = BuildInitialState();

            Current.FlowMode = mode;
            Current.IsSellerGuided = isSellerGuided;
            Current.TotalCoreStages = 5;
            Current.CurrentCoreStage = QuestCoreFlowStage.Intro;
            Current.CurrentImpactHotspotPointer = 0;
            Current.ImpactHotspotIds = PickImpactHotspots(_session?.Hotspots, DefaultImpactHotspotsCount);
            Current.LastStageChangedAt = DateTime.UtcNow;

            // Integração leve com presets: só aplica se não houver preset ativo.
            if (_presets != null && _session != null && !_session.HasPresentationPreset)
            {
                if (mode == QuestPresentationFlowMode.GuidedSalesShort)
                    _presets.ApplyPresetById("QuickPitch");
                else if (mode == QuestPresentationFlowMode.PremiumShowcaseShort)
                    _presets.ApplyPresetById("PremiumShowcase");
            }

            // Onboarding mais enxuto: abre e reduz hints/duração.
            _onboarding?.OpenOnboarding();
            TryApplyShortOnboardingOverrides();

            RefreshState();
        }

        public void SetFullExperience()
        {
            if (Current == null) Current = BuildInitialState();
            Current.FlowMode = QuestPresentationFlowMode.FullExperience;
            Current.IsSellerGuided = false;
            Current.TotalCoreStages = 5;
            Current.CurrentCoreStage = QuestCoreFlowStage.Intro;
            Current.EstimatedRemainingMinutes = EstimateTotalMinutesFor(Current.FlowMode);
            Current.CurrentStageSummary = "Experiência completa (sem orquestração do fluxo curto).";
            Current.IsReadyForClosing = IsReadyForClosing();
            Current.LastStageChangedAt = DateTime.UtcNow;
        }

        public void NextCoreStage()
        {
            if (_session == null || Current == null) return;
            if (Current.FlowMode == QuestPresentationFlowMode.FullExperience)
                StartShortFlow(QuestPresentationFlowMode.GuidedSalesShort, true);

            switch (Current.CurrentCoreStage)
            {
                case QuestCoreFlowStage.Intro:
                    MoveToStage(QuestCoreFlowStage.MainPresentation);
                    break;
                case QuestCoreFlowStage.MainPresentation:
                    MoveToStage(QuestCoreFlowStage.ImpactHotspots);
                    break;
                case QuestCoreFlowStage.ImpactHotspots:
                    MoveToStage(QuestCoreFlowStage.QuickComparison);
                    break;
                case QuestCoreFlowStage.QuickComparison:
                    MoveToStage(QuestCoreFlowStage.Closing);
                    break;
                case QuestCoreFlowStage.Closing:
                    // já no fim
                    break;
            }
        }

        public void PreviousCoreStage()
        {
            if (_session == null || Current == null) return;
            if (Current.FlowMode == QuestPresentationFlowMode.FullExperience) return;

            switch (Current.CurrentCoreStage)
            {
                case QuestCoreFlowStage.Intro:
                    break;
                case QuestCoreFlowStage.MainPresentation:
                    MoveToStage(QuestCoreFlowStage.Intro);
                    break;
                case QuestCoreFlowStage.ImpactHotspots:
                    MoveToStage(QuestCoreFlowStage.MainPresentation);
                    break;
                case QuestCoreFlowStage.QuickComparison:
                    MoveToStage(QuestCoreFlowStage.ImpactHotspots);
                    break;
                case QuestCoreFlowStage.Closing:
                    MoveToStage(QuestCoreFlowStage.QuickComparison);
                    break;
            }
        }

        public void TryGoToClosing()
        {
            if (_session == null || Current == null) return;
            if (Current.FlowMode == QuestPresentationFlowMode.FullExperience)
                StartShortFlow(QuestPresentationFlowMode.GuidedSalesShort, true);

            if (!IsReadyForClosing())
                return;

            MoveToStage(QuestCoreFlowStage.Closing);
        }

        public void RefreshState()
        {
            if (Current == null) return;
            Current.TotalCoreStages = 5;
            Current.IsReadyForClosing = IsReadyForClosing();
            Current.EstimatedRemainingMinutes = EstimateRemainingMinutes(Current.FlowMode, Current.CurrentCoreStage);
            Current.CurrentStageSummary = BuildStageSummary(Current.CurrentCoreStage);
        }

        private QuestShortFlowState BuildInitialState()
        {
            return new QuestShortFlowState
            {
                FlowMode = QuestPresentationFlowMode.FullExperience,
                CurrentCoreStage = QuestCoreFlowStage.Intro,
                TotalCoreStages = 5,
                IsSellerGuided = false,
                EstimatedRemainingMinutes = 10,
                CurrentStageSummary = "Experiência completa.",
                IsReadyForClosing = false,
                LastStageChangedAt = DateTime.UtcNow,
                ImpactHotspotIds = new List<string>(),
                CurrentImpactHotspotPointer = 0
            };
        }

        private void MoveToStage(QuestCoreFlowStage stage)
        {
            if (Current == null) return;
            Current.CurrentCoreStage = stage;
            Current.LastStageChangedAt = DateTime.UtcNow;

            // Limpeza leve de overlays entre etapas
            if (stage != QuestCoreFlowStage.QuickComparison)
                _comparison?.CloseComparison();
            if (stage != QuestCoreFlowStage.Closing)
                _closing?.CloseClosing();
            if (stage != QuestCoreFlowStage.ImpactHotspots)
                _hotspotContext?.CloseContext();

            if (stage == QuestCoreFlowStage.Intro)
            {
                _onboarding?.OpenOnboarding();
                TryApplyShortOnboardingOverrides();
            }
            else if (stage == QuestCoreFlowStage.MainPresentation)
            {
                _onboarding?.StartPresentation();
                _session.NavigationMode = QuestPresentationNavigationMode.Guided;
                _session.CurrentGuidedStepIndex = 0;
                _nav?.OnNavigationChanged?.Invoke();
            }
            else if (stage == QuestCoreFlowStage.ImpactHotspots)
            {
                _session.NavigationMode = QuestPresentationNavigationMode.FocusedHotspot;
                EnsureImpactHotspotFocused(0);
            }
            else if (stage == QuestCoreFlowStage.QuickComparison)
            {
                // comparação rápida do hotspot actual vs próximo
                _comparison?.OpenComparisonFromCurrentHotspot("ShortFlow");
            }
            else if (stage == QuestCoreFlowStage.Closing)
            {
                _closing?.OpenClosing();
            }

            RefreshState();
            _nav?.OnNavigationChanged?.Invoke();
        }

        private void EnsureImpactHotspotFocused(int pointer)
        {
            if (_session?.Hotspots == null || _session.Hotspots.Count == 0) return;
            if (Current == null) return;

            if (Current.ImpactHotspotIds == null || Current.ImpactHotspotIds.Count == 0)
                Current.ImpactHotspotIds = PickImpactHotspots(_session.Hotspots, DefaultImpactHotspotsCount);

            if (pointer < 0) pointer = 0;
            if (pointer >= Current.ImpactHotspotIds.Count) pointer = Current.ImpactHotspotIds.Count - 1;
            Current.CurrentImpactHotspotPointer = pointer;

            var targetId = Current.ImpactHotspotIds[pointer];
            var index = _session.Hotspots.FindIndex(h => h != null && h.Id == targetId);
            if (index < 0) index = 0;
            _session.CurrentHotspotIndex = index;

            // abrir contexto para reforçar pitch (sem obrigar a micro-narrativa)
            var hs = _session.CurrentHotspot;
            if (hs != null)
            {
                _hotspotContext?.OpenContextForHotspot(hs, "ShortFlow");
                _hotspotStory?.BuildAndAssignStorySteps(hs);
            }
        }

        private void TryApplyShortOnboardingOverrides()
        {
            if (_session?.CurrentOnboardingState == null) return;
            if (Current == null) return;
            if (Current.FlowMode == QuestPresentationFlowMode.FullExperience) return;

            var st = _session.CurrentOnboardingState;
            st.EstimatedDurationMinutes = EstimateTotalMinutesFor(Current.FlowMode);
            st.PrimaryGoal = "Sessão curta e impactante: ver essenciais, comparar rápido e fechar CTA.";
            st.InteractionHints = new List<string>
            {
                "Sessão curta (5–10 min): avance por macro etapas.",
                "Priorize hotspots mais impactantes; comparação rápida; feche CTA cedo.",
                "Após o headset: conduza a conversa e próximos passos."
            };
        }

        private bool IsReadyForClosing()
        {
            if (_session == null) return false;
            if (_session.HasClosingOpen) return true;
            if (_session.CurrentClosingState != null && _session.CurrentClosingState.IsReadyToClose) return true;
            if (_session.LastDecisionState == QuestCommercialDecisionState.ReadyToClose) return true;
            var readiness = _session.DecisionSummary?.DecisionReadinessLevel;
            if (readiness.HasValue && readiness.Value == ProposalDecisionReadinessLevel.ReadyToClose) return true;

            // No fluxo curto, após comparação consideramos "pronto o suficiente" para abrir closing.
            if (Current != null && Current.FlowMode != QuestPresentationFlowMode.FullExperience
                && (Current.CurrentCoreStage == QuestCoreFlowStage.QuickComparison || Current.CurrentCoreStage == QuestCoreFlowStage.Closing))
                return true;

            return false;
        }

        private static List<string> PickImpactHotspots(List<ProposalVisualHotspot> hotspots, int count)
        {
            if (hotspots == null || hotspots.Count == 0) return new List<string>();
            if (count <= 0) count = DefaultImpactHotspotsCount;

            return hotspots
                .Where(h => h != null && !string.IsNullOrEmpty(h.Id))
                .OrderByDescending(h => h.IsPremiumUpsell ? 1 : 0)
                .ThenByDescending(h => h.SalesValueScore)
                .ThenBy(h => h.HighlightPriority)
                .Take(count)
                .Select(h => h.Id)
                .ToList();
        }

        private static int EstimateTotalMinutesFor(QuestPresentationFlowMode mode)
        {
            if (mode == QuestPresentationFlowMode.GuidedSalesShort) return 8;
            if (mode == QuestPresentationFlowMode.PremiumShowcaseShort) return 9;
            return 15;
        }

        private static int EstimateRemainingMinutes(QuestPresentationFlowMode mode, QuestCoreFlowStage stage)
        {
            // Heurística simples por etapa; totals ~ 8-10 min.
            int[] guided = { 1, 2, 3, 1, 1 }; // Intro, Main, Hotspots, Comparison, Closing
            int[] premium = { 1, 1, 5, 1, 1 };
            var arr = mode == QuestPresentationFlowMode.PremiumShowcaseShort ? premium
                : mode == QuestPresentationFlowMode.GuidedSalesShort ? guided
                : new[] { 2, 4, 5, 2, 2 };

            var idx = (int)stage;
            if (idx < 0) idx = 0;
            if (idx >= arr.Length) idx = arr.Length - 1;
            var sum = 0;
            for (var i = idx; i < arr.Length; i++)
                sum += arr[i];
            return sum;
        }

        private string BuildStageSummary(QuestCoreFlowStage stage)
        {
            if (Current == null) return "—";
            if (Current.FlowMode == QuestPresentationFlowMode.FullExperience)
                return "Experiência completa (use navegação normal).";

            if (stage == QuestCoreFlowStage.Intro)
                return "Intro: alinhar objetivo e iniciar (onboarding enxuto).";
            if (stage == QuestCoreFlowStage.MainPresentation)
                return "Apresentação principal: roteiro guiado (1–2 min).";
            if (stage == QuestCoreFlowStage.ImpactHotspots)
                return $"Hotspots de impacto: {Mathf.Min(DefaultImpactHotspotsCount, Current.ImpactHotspotIds?.Count ?? 0)} foco(s) prioritário(s).";
            if (stage == QuestCoreFlowStage.QuickComparison)
                return "Comparação rápida: reforçar escolha e clareza.";
            if (stage == QuestCoreFlowStage.Closing)
                return "Fechamento: CTA e próximos passos (abrir closing cedo).";
            return "—";
        }
    }
}

