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 narrativa de apresentação comercial a partir do projeto (tema, itens, zonas, orçamento, fornecedores).
    /// </summary>
    public class MockProposalPresentationService : IProposalPresentationService
    {
        public IReadOnlyList<ProposalPresentationStep> GeneratePresentation(EventProject project)
        {
            var steps = new List<ProposalPresentationStep>();
            if (project == null)
            {
                steps.Add(CreateStep("step-welcome", "Bem-vindo", "Apresentação da proposta.", ProposalPresentationStepType.Welcome, 0, true));
                steps.Add(CreateStep("step-closing", "Encerramento", "Obrigado pela atenção.", ProposalPresentationStepType.Closing, 99, false));
                return steps;
            }

            var order = 0;
            steps.Add(CreateStep("step-welcome", "Bem-vindo", $"Proposta: {project.Name ?? "Evento"}. Vamos percorrer a composição e o investimento.", ProposalPresentationStepType.Welcome, order++, true));

            var themeService = ServiceRegistry.Instance.Get<IVisualThemeService>();
            if (themeService != null && !string.IsNullOrEmpty(project.SelectedThemeId))
            {
                var theme = themeService.GetById(project.SelectedThemeId);
                if (theme != null)
                    steps.Add(CreateStep("step-theme", "Direção estética", $"{theme.Name}. {theme.Description} Mood: {theme.Mood ?? "—"}.", ProposalPresentationStepType.ThemeOverview, order++, true));
            }

            var layoutService = ServiceRegistry.Instance.Get<ISpaceLayoutService>();
            var showroomService = ServiceRegistry.Instance.Get<IShowroomService>();
            var assignments = project.ItemSlotAssignments ?? new List<ItemSlotAssignment>();
            var slotToZone = new Dictionary<string, PlacementZoneType>();
            if (layoutService != null)
                foreach (var slot in layoutService.GetBySpaceId(project.SpaceId ?? ""))
                    slotToZone[slot.Id] = slot.PlacementZone;

            var zoneToItemIds = new Dictionary<PlacementZoneType, List<string>>();
            foreach (var a in assignments)
            {
                if (string.IsNullOrEmpty(a.SlotId) || !slotToZone.TryGetValue(a.SlotId, out var zone)) continue;
                if (!zoneToItemIds.ContainsKey(zone)) zoneToItemIds[zone] = new List<string>();
                if (!string.IsNullOrEmpty(a.ShowroomItemId)) zoneToItemIds[zone].Add(a.ShowroomItemId);
            }

            var zoneSteps = new[] {
                (PlacementZoneType.Entrance, ProposalPresentationStepType.EntranceHighlight, "Entrada", "Destaque da entrada e recepção."),
                (PlacementZoneType.Center, ProposalPresentationStepType.MainAreaHighlight, "Área central", "Composição da área central."),
                (PlacementZoneType.DiningArea, ProposalPresentationStepType.DiningHighlight, "Área de refeição", "Mesas, buffet e serviço."),
                (PlacementZoneType.StageArea, ProposalPresentationStepType.StageHighlight, "Palco", "Palco e cerimônia/apresentação."),
                (PlacementZoneType.LoungeArea, ProposalPresentationStepType.LoungeHighlight, "Lounge", "Área de convivência."),
                (PlacementZoneType.WallArea, ProposalPresentationStepType.WallHighlight, "Parede e apoio", "Elementos de apoio e parede.")
            };

            foreach (var (zone, stepType, title, desc) in zoneSteps)
            {
                if (!zoneToItemIds.TryGetValue(zone, out var itemIds) || itemIds.Count == 0) continue;
                var itemNames = showroomService != null ? itemIds.Select(id => showroomService.GetById(id)?.Name).Where(n => n != null).ToList() : new List<string>();
                var descFull = itemNames.Count > 0 ? $"{desc} Itens: {string.Join(", ", itemNames)}." : desc;
                steps.Add(CreateStep($"step-{zone}", title, descFull, stepType, order++, false, itemIds, new List<PlacementZoneType> { zone }));
            }

            if (project.SupplierIds != null && project.SupplierIds.Count > 0)
            {
                var supplierService = ServiceRegistry.Instance.Get<ISupplierService>();
                var names = project.SupplierIds.Select(id => supplierService?.GetById(id)?.Name).Where(n => n != null).ToList();
                var supplierText = names.Count > 0 ? string.Join(", ", names) : $"{project.SupplierIds.Count} fornecedor(es)";
                steps.Add(CreateStep("step-suppliers", "Fornecedores", $"Parceiros envolvidos: {supplierText}.", ProposalPresentationStepType.SupplierHighlight, order++, false));
            }

            var pricingService = ServiceRegistry.Instance.Get<IProposalPricingService>();
            var summary = pricingService?.GetPricingSummary(project);
            if (summary != null && (summary.ItemCount > 0 || summary.TotalEstimated > 0))
            {
                var budgetDesc = $"{summary.ItemCount} item(ns). Valor estimado total: R$ {summary.TotalEstimated:N0}. {summary.SupplierCount} fornecedor(es).";
                steps.Add(CreateStep("step-budget", "Resumo orçamentário", budgetDesc, ProposalPresentationStepType.BudgetSummary, order++, true));
            }

            steps.Add(CreateStep("step-closing", "Encerramento", "Proposta apresentada. Próximos passos: validação e contratação.", ProposalPresentationStepType.Closing, order++, false));
            return steps;
        }

        private static ProposalPresentationStep CreateStep(string id, string title, string description,
            ProposalPresentationStepType stepType, int displayOrder, bool isHighlight,
            List<string> relatedItemIds = null, List<PlacementZoneType> relatedZones = null)
        {
            return new ProposalPresentationStep
            {
                Id = id,
                Title = title,
                Description = description,
                StepType = stepType,
                DisplayOrder = displayOrder,
                IsHighlight = isHighlight,
                RelatedShowroomItemIds = relatedItemIds ?? new List<string>(),
                RelatedPlacementZones = relatedZones ?? new List<PlacementZoneType>()
            };
        }
    }
}
