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

namespace EventsAppQuest.Infrastructure.Services
{
    /// <summary>
    /// Implementação mock do serviço de layout do espaço. Popula slots lógicos por espaço.
    /// </summary>
    public class MockSpaceLayoutService : ISpaceLayoutService
    {
        private readonly List<SpaceLayoutSlot> _slots = new List<SpaceLayoutSlot>();

        public MockSpaceLayoutService()
        {
            foreach (var spaceId in new[] { "space-1", "space-2", "space-3" })
                AddSlotsForSpace(spaceId);
        }

        private void AddSlotsForSpace(string spaceId)
        {
            var order = 0;
            _slots.Add(CreateSlot(spaceId, $"{spaceId}-entrance", "Entrada principal", PlacementZoneType.Entrance, SpatialAnchorType.Floor, 1, 0, false, true, ++order, true, 8, 90));
            _slots.Add(CreateSlot(spaceId, $"{spaceId}-center", "Área central", PlacementZoneType.Center, SpatialAnchorType.Freestanding, 3, 30, false, true, ++order, true, 5, 70));
            _slots.Add(CreateSlot(spaceId, $"{spaceId}-stage", "Palco", PlacementZoneType.StageArea, SpatialAnchorType.Floor, 2, 0, false, true, ++order, false, 9, 30));
            _slots.Add(CreateSlot(spaceId, $"{spaceId}-dining", "Área de mesas", PlacementZoneType.DiningArea, SpatialAnchorType.Tabletop, 4, 40, true, true, ++order, false, 8, 40));
            _slots.Add(CreateSlot(spaceId, $"{spaceId}-lounge", "Lounge", PlacementZoneType.LoungeArea, SpatialAnchorType.Tabletop, 2, 20, true, false, ++order, false, 4, 20));
            _slots.Add(CreateSlot(spaceId, $"{spaceId}-wall", "Parede de apoio", PlacementZoneType.WallArea, SpatialAnchorType.Wall, 2, 0, false, false, ++order, false, 2, 10));
        }

        private static SpaceLayoutSlot CreateSlot(string spaceId, string id, string name,
            PlacementZoneType zone, SpatialAnchorType anchor, int capacityHint, int capacityContribution, bool isSeatingArea, bool isPrimary, int displayOrder,
            bool isCirculationCritical = false, int accessPriority = 0, int congestionRiskWeight = 0)
        {
            return new SpaceLayoutSlot
            {
                Id = id,
                Name = name,
                SpaceId = spaceId,
                PlacementZone = zone,
                AnchorType = anchor,
                CapacityHint = capacityHint,
                CapacityContribution = capacityContribution,
                IsSeatingArea = isSeatingArea,
                IsPrimary = isPrimary,
                IsCirculationCritical = isCirculationCritical,
                AccessPriority = accessPriority,
                CongestionRiskWeight = congestionRiskWeight,
                DisplayOrder = displayOrder
            };
        }

        public IReadOnlyList<SpaceLayoutSlot> GetBySpaceId(string spaceId)
        {
            if (string.IsNullOrEmpty(spaceId)) return new List<SpaceLayoutSlot>();
            return _slots.Where(s => s.SpaceId == spaceId).OrderBy(s => s.DisplayOrder).ToList();
        }

        public SpaceLayoutSlot GetById(string slotId) => _slots.Find(s => s.Id == slotId);

        public IReadOnlyList<SpaceLayoutSlot> GetCompatibleSlots(string spaceId, PlacementZoneType? zone, SpatialAnchorType? anchor)
        {
            var list = GetBySpaceId(spaceId);
            if (zone == null && anchor == null) return list;
            return list.Where(s =>
                (!zone.HasValue || s.PlacementZone == zone.Value) &&
                (!anchor.HasValue || s.AnchorType == anchor.Value)
            ).ToList();
        }
    }
}
