using adas_core.Domain.Enums;
using adas_core.Domain.Models;
using adas_core.Domain.Models.MongoModels;
using adas_core.Infrastructure.Utils.MongoMaps.Interfaz;
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
using LightBeacon = adas_core.Domain.Models.MongoModels.LightBeacon;

namespace adas_core.Infrastructure.Utils.MongoMaps;

/// <summary>
/// Provides a proof-of-concept implementation of the <see cref="IEntityMapContributor"/> interface for contributing entity mapping logic.
/// </summary>
/// <remarks>
/// This class serves as a demonstrative or experimental implementation of entity map contribution behavior, intended to validate the contract defined by <see cref="IEntityMapContributor"/>.
/// </remarks>
public class PoCMapContributor : IEntityMapContributor
{
    /// <summary>
    /// Registers BSON class maps for PointOfCare-related types (PointOfCare, PointOfCareConfiguration, PoCMapping, PoCMappingItem, and PoCSettings) with the MongoDB driver, configuring serialization options such as element names, default values, null handling, and enum string serialization. Each registration is performed only if a class map for the type has not already been registered.
    /// </summary>
    public void RegisterMaps()
        {
            if (!BsonClassMap.IsClassMapRegistered(typeof(PointOfCare)))
                BsonClassMap.RegisterClassMap<PointOfCare>(cm =>
                {
                    cm.AutoMap();
                    cm.MapIdMember(c => c.Id).SetElementName("_id");
                    cm.MapMember(c => c.Room).SetDefaultValue(string.Empty);
                    cm.MapMember(c => c.Bed).SetDefaultValue(string.Empty);
                    cm.MapMember(c => c.Hall).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.UnitId);
                    cm.MapMember(c => c.Configuration).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Status)
                        .SetSerializer(new EnumSerializer<StatusEnum.PointOfCare>(BsonType.String));
                    cm.MapMember(c => c.AdmissionId).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.IsActive).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.IsVisible).SetIgnoreIfNull(true);
                    cm.UnmapMember(c => c.UnitName);
                    cm.UnmapMember(c => c.Unit);
                    cm.UnmapMember(c => c.Location);
                    cm.UnmapMember(c => c.Observations);
                    cm.UnmapMember(c => c.HasPatient);
                    cm.UnmapMember(c => c.Patientid);
                    cm.UnmapMember(c => c.Patient);
                    cm.UnmapMember(c => c.Admission);
                    
                });
            if (!BsonClassMap.IsClassMapRegistered(typeof(PointOfCareConfiguration)))
                BsonClassMap.RegisterClassMap<PointOfCareConfiguration>(cm =>
                {
                    cm.AutoMap();
                    cm.MapMember(c => c.BeaconIdList)
                        .SetDefaultValue(new List<ObjectId>());
                    cm.MapMember(c => c.CameraIdList)
                        .SetDefaultValue(new List<ObjectId>());
                    cm.MapMember(c => c.RelayIdList).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Type).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Id).SetIgnoreIfNull(true);
                    
                    cm.MapMember(c => c.BeaconList)
                        .SetIgnoreIfNull(true)
                        .SetIsRequired(false);
    
                    cm.MapMember(c => c.CameraList)
                        .SetIgnoreIfNull(true)
                        .SetIsRequired(false);
    
                    cm.MapMember(c => c.RelayList)
                        .SetIgnoreIfNull(true)
                        .SetIsRequired(false);
                });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(PoCMapping)))
                BsonClassMap.RegisterClassMap<PoCMapping>(cm =>
                {
                    cm.AutoMap();
                    cm.MapIdMember(c => c.Id).SetElementName("_id");
                    cm.MapMember(c => c.PointOfCares).SetDefaultValue(new List<PoCMappingItem>());
                });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(PoCMappingItem)))
                BsonClassMap.RegisterClassMap<PoCMappingItem>(cm =>
                {
                    cm.AutoMap();
                    cm.MapMember(c => c.NewPoC).SetElementName("new");
                    cm.MapMember(c => c.OriginalPoC).SetElementName("original");
                    cm.MapMember(c => c.Beds).SetDefaultValue(new List<List<string>>());
                });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(PoCSettings)))
                BsonClassMap.RegisterClassMap<PoCSettings>(cm =>
                {
                    cm.AutoMap();
                    cm.MapIdMember(c => c.Id).SetElementName("_id");
                    cm.MapMember(c => c.PatientLocation).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.ManualRelayStatus)
                        .SetIgnoreIfNull(true)
                        .SetSerializer(
                            new NullableSerializer<RelayEnum.Status>(
                                new EnumSerializer<RelayEnum.Status>(BsonType.String)));
                });
        }
}