using adas_core.Domain.Enums;
using adas_core.Domain.Models.Masters;
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 a map contributor for the master list entity, providing mapping logic through the <see cref="IEntityMapContributor"/> contract.
/// </summary>
/// <remarks>
/// Use this contributor when defining or extending the mapping configuration associated with master list entities.
/// </remarks>
public class MasterListMapContributor : IEntityMapContributor
{
    /// <summary>
    /// Registers BSON class maps for domain types (such as <see cref="Element"/>, <see cref="OptionList"/>, <see cref="MasterList"/>, <see cref="Locale"/>, and their derived option lists) to control their MongoDB serialization. Each registration is performed only when no class map already exists for the type, and applies domain-specific settings including default values, null-ignore rules, discriminator naming, and custom serializers for enums, locale fields, and identifiers.
    /// </summary>
    public void RegisterMaps()
        {
            if (!BsonClassMap.IsClassMapRegistered(typeof(Element)))
                BsonClassMap.RegisterClassMap<Element>(cm =>
                {
                    cm.AutoMap();
                    cm.GetMemberMap(c => c.Title).SetDefaultValue(string.Empty);
                    cm.GetMemberMap(c => c.IsRequired).SetDefaultValue(false);
                    cm.GetMemberMap(c => c.IsList).SetDefaultValue(false);
                    cm.GetMemberMap(c => c.ListName).SetDefaultValue(string.Empty);
                });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(OptionListDetails)))
                BsonClassMap.RegisterClassMap<OptionListDetails>(cm =>
                {
                    cm.AutoMap();
                    cm.GetMemberMap(c => c.OptionType).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.Name).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.IconDefault).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.IconCategory).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.IconColor).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.Color).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.BgColor).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.Description).SetIgnoreIfNull(true);
                });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(MasterList)))
                BsonClassMap.RegisterClassMap<MasterList>(cm =>
                {
                    cm.AutoMap();
                    cm.UnmapMember(c => c.ManualObservationName);
                    cm.UnmapMember(c => c.AutoObservationName);
                    cm.MapIdMember(c => c.Id).SetElementName("_id");
                    cm.GetMemberMap(c => c.DefaultLocale).SetIgnoreIfNull(true).SetSerializer(
                        new NullableSerializer<LocaleEnum>(new EnumSerializer<LocaleEnum>(BsonType.String))
                    );
                    cm.GetMemberMap(c => c.Name).SetDefaultValue(string.Empty);
                    cm.GetMemberMap(c => c.Description).SetDefaultValue(string.Empty);
                    cm.GetMemberMap(c => c.OptionListDetails).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.CanAddElement).SetDefaultValue(false);
                    cm.MapMember(c => c.ListType)
                        .SetSerializer(new EnumSerializer<MasterListType>(BsonType.String));
                    cm.MapMember(c => c.Options).SetDefaultValue(new List<OptionList>());
                });
            if (!BsonClassMap.IsClassMapRegistered(typeof(LocaleItem)))
                BsonClassMap.RegisterClassMap<LocaleItem>(cm =>
                {
                    cm.AutoMap();
                    cm.GetMemberMap(c => c.Name).SetIgnoreIfNull(true);
                });
            if (!BsonClassMap.IsClassMapRegistered(typeof(Locale)))
                BsonClassMap.RegisterClassMap<Locale>(cm =>
                {
                    cm.AutoMap();
                    cm.GetMemberMap(c => c.Es).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.Pt).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.Eng).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.Ca).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.Zh).SetIgnoreIfNull(true);
                });
            if (!BsonClassMap.IsClassMapRegistered(typeof(OptionList)))
                BsonClassMap.RegisterClassMap<OptionList>(cm =>
                {
                    cm.AutoMap();
                    cm.MapIdMember(c => c.Id).SetElementName("_id").SetSerializer(new NullableSerializer<ObjectId>(new ObjectIdSerializer(BsonType.ObjectId)));;
                    cm.GetMemberMap(c => c.OptionType).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.Name).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.LocaleItems).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.IconDefault).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.IconCategory).SetIgnoreIfNull(true); 
                    cm.GetMemberMap(c => c.IconColor).SetIgnoreIfNull(true); 
                    cm.GetMemberMap(c => c.Color).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.BgColor).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.Description).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.InitDate).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.EndDate).SetIgnoreIfNull(true);
                    cm.GetMemberMap(c => c.IsDefault).SetIgnoreIfNull(true);
                    cm.SetDiscriminator(nameof(OptionList));
                });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(AltableOptionList)))
                BsonClassMap.RegisterClassMap<AltableOptionList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(VisitOptionList)))
                BsonClassMap.RegisterClassMap<VisitOptionList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(AccessControlList)))
                BsonClassMap.RegisterClassMap<AccessControlList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(MobilityOptionList)))
                BsonClassMap.RegisterClassMap<MobilityOptionList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(TherapeuticCeilingList)))
                BsonClassMap.RegisterClassMap<TherapeuticCeilingList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(PassiveSittingList)))
                BsonClassMap.RegisterClassMap<PassiveSittingList>(cm => { cm.AutoMap(); });
            
            if (!BsonClassMap.IsClassMapRegistered(typeof(GenericList)))
                BsonClassMap.RegisterClassMap<GenericList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(ProcedureList)))
                BsonClassMap.RegisterClassMap<ProcedureList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(TestList)))
                BsonClassMap.RegisterClassMap<TestList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(DiagnosisList)))
                BsonClassMap.RegisterClassMap<DiagnosisList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(OriginList)))
                BsonClassMap.RegisterClassMap<OriginList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(DestinationList)))
                BsonClassMap.RegisterClassMap<DestinationList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(InternalDestinationList)))
                BsonClassMap.RegisterClassMap<InternalDestinationList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(TreatmentList)))
                BsonClassMap.RegisterClassMap<TreatmentList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(PatientStatusList)))
                BsonClassMap.RegisterClassMap<PatientStatusList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(ServiceList)))
                BsonClassMap.RegisterClassMap<ServiceList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(AllergyList)))
                BsonClassMap.RegisterClassMap<AllergyList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(DoctorTypeList)))
                BsonClassMap.RegisterClassMap<DoctorTypeList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(DoctorList)))
                BsonClassMap.RegisterClassMap<DoctorList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(InsulationList)))
                BsonClassMap.RegisterClassMap<InsulationList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(DischargeStatusList)))
                BsonClassMap.RegisterClassMap<DischargeStatusList>(cm => { cm.AutoMap(); });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(LanguageBarrierList)))
                BsonClassMap.RegisterClassMap<LanguageBarrierList>(cm => { cm.AutoMap(); });
        }
}