using adas_core.Domain.Enums;
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;

namespace adas_core.Infrastructure.Utils.MongoMaps;

/// <summary>
/// Represents an entity mapping contributor that provides mapping configuration for units.
/// </summary>
/// <remarks>
/// Implements <see cref="IEntityMapContributor"/> to integrate unit-specific mapping logic into the entity mapping pipeline.
/// </remarks>
public class UnitMapContributor : IEntityMapContributor
{
    /// <summary>
    /// Registers BSON class maps for the <see cref="Unit"/> and <see cref="UnitConfiguration"/> types used in MongoDB serialization.
    /// Each registration is performed only if no class map has been previously registered for the target type, and configures
    /// field-level mappings, default values, ignored properties, and custom serializers as required by the domain model.
    /// </summary>
    public void RegisterMaps()
        {
            if (!BsonClassMap.IsClassMapRegistered(typeof(Unit)))
                BsonClassMap.RegisterClassMap<Unit>(cm =>
                {
                    cm.AutoMap();
                    cm.MapIdMember(c => c.Id).SetElementName("_id").SetIsRequired(true);
                    cm.GetMemberMap(c => c.Title).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.Name).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.LastUpdate).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.PointOfCareIds).SetIgnoreIfNull(true);
    
                    cm.UnmapMember(c => c.PocCount);
    
                    cm.MapMember(c => c.Status)
                        .SetDefaultValue(StatusEnum.Type.Ok)
                        .SetSerializer(
                            new NullableSerializer<StatusEnum.Type>(new EnumSerializer<StatusEnum.Type>(BsonType.String)));
                    cm.MapMember(c => c.Configuration).SetDefaultValue(new UnitConfiguration());
    
                    cm.GetMemberMap(c => c.AltableOptionListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.AllergyListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.DestinationListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.InternalDestinationListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.DiagnosisListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.DoctorListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.DoctorTypeListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.InsulationListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.MobilityOptionListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.OriginListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.PatientStatusListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.ProcedureListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.TestListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.ServiceListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.TherapeuticCeilingListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.TreatmentListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.VisitOptionListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.AccessControlListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.LanguageBarrierListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.DischargeStatusListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.PassiveSittingListId).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.GenericListId).SetIgnoreIfNull(true);
    
                    // No mapear estos campos
                    cm.UnmapProperty(c => c.AllergyList);
                    cm.UnmapProperty(c => c.DestinationList);
                    cm.UnmapProperty(c => c.DiagnosisList);
                    cm.UnmapProperty(c => c.DoctorList);
                    cm.UnmapProperty(c => c.DoctorTypeList);
                    cm.UnmapProperty(c => c.InsulationList);
                    cm.UnmapProperty(c => c.MobilityOptionList);
                    cm.UnmapProperty(c => c.OriginList);
                    cm.UnmapProperty(c => c.PatientStatusList);
                    cm.UnmapProperty(c => c.ProcedureList);
                    cm.UnmapProperty(c => c.TestList);
                    cm.UnmapProperty(c => c.AltableOptionList);
                    cm.UnmapProperty(c => c.DischargeStatusList);
                    cm.UnmapProperty(c => c.ServiceList);
                    cm.UnmapProperty(c => c.TherapeuticCeilingList);
                    cm.UnmapProperty(c => c.TreatmentList);
                    cm.UnmapProperty(c => c.VisitOptionList);
                    cm.UnmapProperty(c => c.PassiveSittingList);
                    cm.UnmapProperty(c => c.GenericList);
                    cm.UnmapProperty(c => c.LanguageBarrierList);
                    cm.UnmapProperty(c => c.PointOfCares);
                    cm.UnmapProperty(c => c.InternalDestinationList);
                });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(UnitConfiguration)))
                BsonClassMap.RegisterClassMap<UnitConfiguration>(cm =>
                {
                    cm.AutoMap();
                    cm.MapMember(c => c.AutoAdt).SetDefaultValue(false);
                    cm.MapMember(c => c.ManualDischarge).SetDefaultValue(true);
                    cm.MapMember(c => c.ManualAdmit).SetDefaultValue(true);
                    cm.MapMember(c => c.ManualMove).SetDefaultValue(true);
                    cm.MapMember(c => c.ManualEdit).SetDefaultValue(true);
                    cm.MapMember(c => c.PlanDisplayConfiguration).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.SmartDisplayConfiguration).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.StandarDisplayConfiguration).SetIgnoreIfNull(true);
                });
        }
}