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

namespace EventsAppQuest.Infrastructure.Services
{
    /// <summary>
    /// Gera estados visuais da cena por fase a partir de moment plans, transições, hotspots, tema e showroom.
    /// </summary>
    public class MockProposalSceneStateService : IProposalSceneStateService
    {
        public IReadOnlyList<ProposalSceneState> GenerateSceneStates(EventProject project, EventProjectProposal proposal)
        {
            var states = new List<ProposalSceneState>();
            if (proposal == null) return states;

            var planningService = ServiceRegistry.Instance.Get<IEventMomentPlanningService>();
            var themeService = ServiceRegistry.Instance.Get<IVisualThemeService>();

            var plans = proposal.MomentPlans ?? new List<ProposalMomentPlan>();
            if (plans.Count == 0 && planningService != null)
            {
                var generated = planningService.GenerateMomentPlan(project, proposal);
                if (generated != null) { proposal.MomentPlans = new List<ProposalMomentPlan>(generated); plans = proposal.MomentPlans; }
            }

            var phases = planningService?.GetAvailablePhases(project?.EventTemplateId)?.OrderBy(p => p.DisplayOrder).ToList() ?? new List<EventMomentPhase>();
            var phaseById = phases.ToDictionary(p => p.Id);

            var orderedPlans = new List<ProposalMomentPlan>();
            foreach (var phase in phases)
            {
                var plan = plans.FirstOrDefault(p => p.PhaseId == phase.Id);
                if (plan != null)
                    orderedPlans.Add(plan);
            }

            var transitions = proposal.MomentTransitions ?? new List<EventMomentTransition>();
            var hotspots = proposal.VisualHotspots ?? new List<ProposalVisualHotspot>();
            var tourSteps = proposal.GuidedTourSteps ?? new List<ProposalGuidedTourStep>();
            var proposalItemIds = new HashSet<string>(proposal.ShowroomItemIds ?? new List<string>());

            string themeMood = null;
            if (themeService != null && !string.IsNullOrEmpty(proposal.ThemeId))
            {
                var theme = themeService.GetById(proposal.ThemeId);
                if (theme != null) themeMood = theme.Mood;
            }

            for (var i = 0; i < orderedPlans.Count; i++)
            {
                var plan = orderedPlans[i];
                var phase = phaseById.TryGetValue(plan.PhaseId, out var p) ? p : null;
                var name = phase?.Name ?? plan.PhaseId;
                var description = !string.IsNullOrEmpty(plan.HighlightText) ? plan.HighlightText : phase?.Description ?? "";

                var activeItems = (plan.RelatedShowroomItemIds ?? new List<string>()).Where(id => proposalItemIds.Contains(id)).ToList();
                var activeZones = plan.RelatedZoneTypes ?? new List<string>();

                var transitionIn = transitions.FirstOrDefault(t => t.ToPhaseId == plan.PhaseId);
                var transitionSummary = FormatTransitionSummary(transitionIn);

                var primaryHotspotIds = GetPrimaryHotspotIdsForPhase(plan.PhaseId, plan.RelatedZoneTypes, tourSteps, hotspots);

                var state = new ProposalSceneState
                {
                    Id = "scene-" + plan.PhaseId,
                    RelatedPhaseId = plan.PhaseId,
                    Name = name,
                    Description = description,
                    ActiveShowroomItemIds = activeItems,
                    ActiveZoneTypes = activeZones,
                    PrimaryHotspotIds = primaryHotspotIds,
                    VisualMood = themeMood ?? "—",
                    TransitionFromPreviousSummary = transitionSummary ?? (i == 0 ? "Início" : "—"),
                    DisplayOrder = phase?.DisplayOrder ?? i
                };
                states.Add(state);
            }

            return states.OrderBy(s => s.DisplayOrder).ToList();
        }

        private static string FormatTransitionSummary(EventMomentTransition t)
        {
            if (t == null) return null;
            var typeStr = t.TransitionType == EventMomentTransitionType.DirectFlow ? "Fluxo direto" :
                t.TransitionType == EventMomentTransitionType.Reconfiguration ? "Reconfiguração" :
                t.TransitionType == EventMomentTransitionType.GuestRelocation ? "Relocação de convidados" :
                t.TransitionType == EventMomentTransitionType.ServiceTurnover ? "Troca de serviço" :
                t.TransitionType == EventMomentTransitionType.ClosingTransition ? "Encerramento" : t.TransitionType.ToString();
            var min = t.EstimatedTransitionMinutes > 0 ? $" ~{t.EstimatedTransitionMinutes} min" : "";
            return typeStr + min;
        }

        private static List<string> GetPrimaryHotspotIdsForPhase(string phaseId, List<string> zoneTypes,
            List<ProposalGuidedTourStep> tourSteps, List<ProposalVisualHotspot> hotspots)
        {
            var stepIdsForPhase = new HashSet<string>(
                (tourSteps ?? new List<ProposalGuidedTourStep>()).Where(s => s.RelatedPhaseId == phaseId).Select(s => s.Id));
            var zoneSet = new HashSet<string>(zoneTypes ?? new List<string>());

            var candidates = (hotspots ?? new List<ProposalVisualHotspot>())
                .Where(h => stepIdsForPhase.Contains(h.RelatedGuidedTourStepId ?? "") ||
                            (zoneSet.Count > 0 && (h.RelatedZoneTypes?.Any(z => zoneSet.Contains(z)) ?? false)))
                .OrderBy(h => h.HighlightPriority)
                .Take(3)
                .Select(h => h.Id)
                .ToList();
            return candidates;
        }
    }
}
