using System;
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 transições entre fases da jornada com base na sequência de MomentPlans, zonas e fornecedores.
    /// </summary>
    public class MockEventMomentTransitionService : IEventMomentTransitionService
    {
        private const string PhaseClosing = "phase-closing";

        public IReadOnlyList<EventMomentTransition> GenerateTransitions(EventProject project, EventProjectProposal proposal)
        {
            var plans = proposal?.MomentPlans;
            if (plans == null || plans.Count < 2)
                return new List<EventMomentTransition>();

            var planningService = ServiceRegistry.Instance.Get<IEventMomentPlanningService>();
            var phases = planningService?.GetAvailablePhases(project?.EventTemplateId)?.ToList() ?? new List<EventMomentPhase>();
            var phaseOrder = phases.OrderBy(p => p.DisplayOrder).Select(p => p.Id).ToList();

            var orderedPlans = new List<ProposalMomentPlan>();
            foreach (var phaseId in phaseOrder)
            {
                var plan = plans.FirstOrDefault(p => p.PhaseId == phaseId);
                if (plan != null)
                    orderedPlans.Add(plan);
            }
            if (orderedPlans.Count < 2)
                return new List<EventMomentTransition>();

            var result = new List<EventMomentTransition>();
            for (var i = 0; i < orderedPlans.Count - 1; i++)
            {
                var from = orderedPlans[i];
                var to = orderedPlans[i + 1];
                var transition = BuildTransition(from, to);
                result.Add(transition);
            }
            return result;
        }

        private static EventMomentTransition BuildTransition(ProposalMomentPlan from, ProposalMomentPlan to)
        {
            var fromZones = new HashSet<string>(from.RelatedZoneTypes ?? new List<string>());
            var toZones = new HashSet<string>(to.RelatedZoneTypes ?? new List<string>());
            var fromHasContent = (from.RelatedShowroomItemIds?.Count ?? 0) > 0;
            var toHasContent = (to.RelatedShowroomItemIds?.Count ?? 0) > 0;
            var overlap = fromZones.Any(z => toZones.Contains(z));
            var fromSuppliers = new HashSet<string>(from.KeySupplierIds ?? new List<string>());
            var toSuppliers = new HashSet<string>(to.KeySupplierIds ?? new List<string>());
            var suppliersChange = !fromSuppliers.SetEquals(toSuppliers);

            EventMomentTransitionType type;
            var requiresReset = false;
            var requiresCoord = false;
            var minutes = 5;
            var smoothness = 85;

            if (to.PhaseId == PhaseClosing)
            {
                type = EventMomentTransitionType.ClosingTransition;
                minutes = 10;
                smoothness = overlap ? 80 : 70;
                requiresCoord = toSuppliers.Count > 0 && suppliersChange;
            }
            else if (fromZones.Contains("DiningArea") != toZones.Contains("DiningArea") && (fromHasContent || toHasContent))
            {
                type = EventMomentTransitionType.ServiceTurnover;
                requiresReset = toZones.Contains("DiningArea") && fromHasContent;
                requiresCoord = true;
                minutes = 10;
                smoothness = 65;
            }
            else if (!overlap && fromHasContent && toHasContent)
            {
                type = EventMomentTransitionType.GuestRelocation;
                requiresReset = true;
                requiresCoord = suppliersChange;
                minutes = 12;
                smoothness = 60;
            }
            else if (fromZones.Count > 0 && toZones.Count > 0 && !overlap)
            {
                type = EventMomentTransitionType.Reconfiguration;
                requiresReset = true;
                requiresCoord = suppliersChange;
                minutes = 15;
                smoothness = 55;
            }
            else
            {
                type = EventMomentTransitionType.DirectFlow;
                requiresReset = false;
                requiresCoord = false;
                minutes = 5;
                smoothness = 90;
            }

            if (requiresReset) smoothness = Math.Max(0, smoothness - 15);
            if (requiresCoord) smoothness = Math.Max(0, smoothness - 10);

            var notes = type == EventMomentTransitionType.DirectFlow ? "Fluxo direto." :
                requiresReset ? "Reconfiguração do espaço recomendada." :
                requiresCoord ? "Coordenação com fornecedores na passagem." : "";

            return new EventMomentTransition
            {
                FromPhaseId = from.PhaseId,
                ToPhaseId = to.PhaseId,
                TransitionType = type,
                EstimatedTransitionMinutes = minutes,
                RequiresSpaceReset = requiresReset,
                RequiresSupplierCoordination = requiresCoord,
                SmoothnessScore = smoothness,
                Notes = notes
            };
        }
    }
}
