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

namespace EventsAppQuest.Infrastructure.Services
{
    /// <summary>
    /// Gera plano de momentos/fases do evento a partir da proposta (narrativa, itens, zonas, fornecedores).
    /// </summary>
    public class MockEventMomentPlanningService : IEventMomentPlanningService
    {
        private static readonly List<EventMomentPhase> DefaultPhases = new List<EventMomentPhase>
        {
            new EventMomentPhase { Id = "phase-reception", Name = "Recepção", Description = "Chegada, boas-vindas e ambientação.", PhaseType = EventMomentPhaseType.Reception, DisplayOrder = 0, IsCoreMoment = true },
            new EventMomentPhase { Id = "phase-ceremony", Name = "Cerimônia", Description = "Momento central (ex.: cerimônia, abertura).", PhaseType = EventMomentPhaseType.Ceremony, DisplayOrder = 1, IsCoreMoment = true },
            new EventMomentPhase { Id = "phase-dining", Name = "Refeição", Description = "Jantar, coffee break ou serviço de catering.", PhaseType = EventMomentPhaseType.Dining, DisplayOrder = 2, IsCoreMoment = true },
            new EventMomentPhase { Id = "phase-presentation", Name = "Apresentação", Description = "Palestras, palco ou área de destaque.", PhaseType = EventMomentPhaseType.Presentation, DisplayOrder = 3, IsCoreMoment = false },
            new EventMomentPhase { Id = "phase-party", Name = "Confraternização", Description = "Festa, networking ou área central.", PhaseType = EventMomentPhaseType.Party, DisplayOrder = 4, IsCoreMoment = false },
            new EventMomentPhase { Id = "phase-networking", Name = "Networking", Description = "Lounge, convivência e contatos.", PhaseType = EventMomentPhaseType.Networking, DisplayOrder = 5, IsCoreMoment = false },
            new EventMomentPhase { Id = "phase-closing", Name = "Encerramento", Description = "Despedida e encerramento do evento.", PhaseType = EventMomentPhaseType.Closing, DisplayOrder = 6, IsCoreMoment = true }
        };

        public IReadOnlyList<EventMomentPhase> GetAvailablePhases(string eventTemplateId = null)
        {
            return DefaultPhases.OrderBy(p => p.DisplayOrder).ToList();
        }

        public IReadOnlyList<ProposalMomentPlan> GenerateMomentPlan(EventProject project, EventProjectProposal proposal)
        {
            var phases = GetAvailablePhases(project?.EventTemplateId).ToList();
            var steps = proposal?.PresentationSteps ?? project?.GeneratedPresentationSteps;
            if (steps == null || steps.Count == 0)
            {
                return phases.Select(p => new ProposalMomentPlan
                {
                    PhaseId = p.Id,
                    EstimatedDurationMinutes = p.IsCoreMoment ? 15 : 0,
                    HighlightText = p.Name
                }).ToList();
            }

            var stepToPhaseType = new Dictionary<ProposalPresentationStepType, EventMomentPhaseType>
            {
                { ProposalPresentationStepType.Welcome, EventMomentPhaseType.Reception },
                { ProposalPresentationStepType.ThemeOverview, EventMomentPhaseType.Reception },
                { ProposalPresentationStepType.EntranceHighlight, EventMomentPhaseType.Reception },
                { ProposalPresentationStepType.WallHighlight, EventMomentPhaseType.Reception },
                { ProposalPresentationStepType.StageHighlight, EventMomentPhaseType.Ceremony },
                { ProposalPresentationStepType.DiningHighlight, EventMomentPhaseType.Dining },
                { ProposalPresentationStepType.MainAreaHighlight, EventMomentPhaseType.Presentation },
                { ProposalPresentationStepType.SupplierHighlight, EventMomentPhaseType.Presentation },
                { ProposalPresentationStepType.LoungeHighlight, EventMomentPhaseType.Networking },
                { ProposalPresentationStepType.BudgetSummary, EventMomentPhaseType.Closing },
                { ProposalPresentationStepType.Closing, EventMomentPhaseType.Closing }
            };

            var phaseTypeToPhase = phases.ToDictionary(p => p.PhaseType);
            var plansByPhase = new Dictionary<string, ProposalMomentPlan>();

            foreach (var step in steps.OrderBy(s => s.DisplayOrder))
            {
                if (!stepToPhaseType.TryGetValue(step.StepType, out var phaseType))
                    continue;
                if (!phaseTypeToPhase.TryGetValue(phaseType, out var phase))
                    continue;

                if (!plansByPhase.TryGetValue(phase.Id, out var plan))
                {
                    plan = new ProposalMomentPlan
                    {
                        PhaseId = phase.Id,
                        RelatedShowroomItemIds = new List<string>(),
                        RelatedZoneTypes = new List<string>(),
                        KeySupplierIds = new List<string>(),
                        EstimatedDurationMinutes = phase.IsCoreMoment ? 20 : 15,
                        HighlightText = phase.Name
                    };
                    plansByPhase[phase.Id] = plan;
                }

                if (step.RelatedShowroomItemIds != null)
                {
                    foreach (var id in step.RelatedShowroomItemIds)
                        if (!string.IsNullOrEmpty(id) && !plan.RelatedShowroomItemIds.Contains(id))
                            plan.RelatedShowroomItemIds.Add(id);
                }
                if (step.RelatedPlacementZones != null)
                {
                    foreach (var z in step.RelatedPlacementZones)
                    {
                        var zStr = z.ToString();
                        if (!plan.RelatedZoneTypes.Contains(zStr))
                            plan.RelatedZoneTypes.Add(zStr);
                    }
                }
                if (step.IsHighlight && !string.IsNullOrEmpty(step.Title))
                    plan.HighlightText = step.Title;
            }

            var supplierIds = project?.SupplierIds ?? new List<string>();
            foreach (var plan in plansByPhase.Values)
            {
                if (plan.RelatedShowroomItemIds.Count > 0 && supplierIds.Count > 0)
                {
                    plan.KeySupplierIds = new List<string>(supplierIds);
                    var durationByPhase = new Dictionary<EventMomentPhaseType, int>
                    {
                        { EventMomentPhaseType.Reception, 20 },
                        { EventMomentPhaseType.Ceremony, 30 },
                        { EventMomentPhaseType.Dining, 45 },
                        { EventMomentPhaseType.Presentation, 25 },
                        { EventMomentPhaseType.Party, 30 },
                        { EventMomentPhaseType.Networking, 25 },
                        { EventMomentPhaseType.Closing, 15 }
                    };
                    var phase = phases.FirstOrDefault(p => p.Id == plan.PhaseId);
                    if (phase != null && durationByPhase.TryGetValue(phase.PhaseType, out var mins))
                        plan.EstimatedDurationMinutes = mins;
                }
            }

            var result = new List<ProposalMomentPlan>();
            foreach (var phase in phases.OrderBy(p => p.DisplayOrder))
            {
                if (plansByPhase.TryGetValue(phase.Id, out var plan))
                    result.Add(plan);
                else
                    result.Add(new ProposalMomentPlan { PhaseId = phase.Id, EstimatedDurationMinutes = phase.IsCoreMoment ? 15 : 0, HighlightText = phase.Name });
            }
            return result;
        }
    }
}
