using adas_core.Domain.Enums;
using adas_core.Domain.Models.MongoModels;
using adas_core.Domain.Models.Pumps;
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 contributor that provides mapping logic for pump-related entities within an entity mapping context.
    /// </summary>
    public class PumpMapContributor : IEntityMapContributor
    {
        public void RegisterMaps()
        {
            // ============================================================
            // CommonPumpTypes: PumpValue
            // ============================================================
            if (!BsonClassMap.IsClassMapRegistered(typeof(CommonPumpTypes.PumpValue)))
            {
                BsonClassMap.RegisterClassMap<CommonPumpTypes.PumpValue>(cm =>
                {
                    cm.AutoMap();
                    cm.MapMember(c => c.Value).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Units).SetIgnoreIfNull(true);
                });
            }

            // ============================================================
            // CommonPumpTypes: SyringeDetails
            // ============================================================
            if (!BsonClassMap.IsClassMapRegistered(typeof(CommonPumpTypes.SyringeDetails)))
            {
                BsonClassMap.RegisterClassMap<CommonPumpTypes.SyringeDetails>(cm =>
                {
                    cm.AutoMap();
                    cm.MapMember(c => c.Type).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Manufacturer).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Volume).SetIgnoreIfNull(true);
                });
            }

            // ============================================================
            // PatientPumpObservation (nuevo modelo simplificado)
            // ============================================================
            if (!BsonClassMap.IsClassMapRegistered(typeof(PumpObservation)))
            {
                BsonClassMap.RegisterClassMap<PumpObservation>(cm =>
                {
                    cm.AutoMap();
                    cm.MapIdMember(c => c.Id).SetElementName("_id");

                    // Identificadores
                    cm.MapMember(c => c.DeviceId).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.RackId).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.DeviceTypeMdc).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.InfusionId).SetIgnoreIfNull(true);

                    cm.MapMember(c => c.PatientId).SetIgnoreIfNull(true).SetElementName("patientid");

                    
                    //campos para Alaris
                    cm.MapMember(c => c.Pressure).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.DiluentVolume).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.PatientHeight).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.BasalRate).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.TotalAux).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.GatewayNumber).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Number).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Total).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.IsAux).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Code).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Name).SetIgnoreIfNull(true);
                    
                    cm.UnmapMember(c => c.UiConfiguration);
                    cm.MapMember(c => c.AlarmMode)
                        .SetIgnoreIfNull(true)
                        .SetSerializer(new NullableSerializer<PumpEnum.AlarmMode>(
                            new EnumSerializer<PumpEnum.AlarmMode>(BsonType.String)));

                    // Tiempo
                    cm.MapMember(c => c.Time).SetIgnoreIfNull(true);

                    cm.MapMember(c => c.MessageType)
                        .SetIgnoreIfNull(true)
                        .SetSerializer(new EnumSerializer<PumpEnum.PumpMessageType>(BsonType.String));

                    // Estado de infusión
                    cm.MapMember(c => c.IsInfusing).SetIgnoreIfNull(true);

                    cm.MapMember(c => c.InfusingStatus)
                        .SetIgnoreIfNull(true)
                        .SetSerializer(new NullableSerializer<PumpEnum.InfusingStatus>(
                            new EnumSerializer<PumpEnum.InfusingStatus>(BsonType.String)));

                    cm.MapMember(c => c.Status)
                        .SetIgnoreIfNull(true)
                        .SetSerializer(new NullableSerializer<PumpEnum.Status>(
                            new EnumSerializer<PumpEnum.Status>(BsonType.String)));

                    cm.MapMember(c => c.PumpMode)
                        .SetIgnoreIfNull(true)
                        .SetSerializer(new NullableSerializer<PumpEnum.Mode>(
                            new EnumSerializer<PumpEnum.Mode>(BsonType.String)));

                    cm.MapMember(c => c.ActiveSourceInfo).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.InfusionModeDetail).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.NotDeliveringReason).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Source).SetIgnoreIfNull(true);

                    // Métricas
                    cm.MapMember(c => c.FlowFluid).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Rate).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.VolumeInfused).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.FluidDelivTotal).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.FluidDelivTotalSet).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.VolumeRemaining).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Vtbi).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.TimeRemaining).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.TimeProgrammed).SetIgnoreIfNull(true);

                    // Medicación
                    cm.MapMember(c => c.DrugName).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.DrugId).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Concentration).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.DoseRate).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.DrugAmount).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.DrugDoseDelivered).SetIgnoreIfNull(true);

                    // Paciente
                    cm.MapMember(c => c.PatientWeight).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Syringe).SetIgnoreIfNull(true);

                    // Ubicación
                    cm.MapMember(c => c.DeviceIp).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.PillarAssembly).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.PillarRackSlot).SetIgnoreIfNull(true);

                    // ALARMAS
                    cm.MapMember(c => c.AlarmType)
                        .SetIgnoreIfNull(true)
                        .SetSerializer(new NullableSerializer<PumpEnum.AlarmType>(
                            new EnumSerializer<PumpEnum.AlarmType>(BsonType.String)));

                    cm.MapMember(c => c.AlarmDescription).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.AlarmState).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.AlarmInactivationState).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.AlarmPriority).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.AlarmTypeMdc).SetIgnoreIfNull(true);

                    cm.MapMember(c => c.EventPhase)
                        .SetIgnoreIfNull(true)
                        .SetSerializer(new NullableSerializer<PumpEnum.EventPhase>(
                            new EnumSerializer<PumpEnum.EventPhase>(BsonType.String)));

                    cm.MapMember(c => c.AlertSourceMdc).SetIgnoreIfNull(true);

                    // EVENTOS (PCD-10)
                    cm.MapMember(c => c.Event)
                        .SetIgnoreIfNull(true)
                        .SetSerializer(new NullableSerializer<PumpEnum.Event>(
                            new EnumSerializer<PumpEnum.Event>(BsonType.String)));
                });
            }


            // ============================================================
            // PumpState
            // ============================================================
            if (!BsonClassMap.IsClassMapRegistered(typeof(PumpState)))
            {
                BsonClassMap.RegisterClassMap<PumpState>(cm =>
                {
                    cm.AutoMap();
                    cm.MapIdMember(c => c.Id).SetElementName("_id");

                    cm.MapMember(c => c.DeviceId).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.RackId).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.DeviceTypeMdc).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.DeviceIp).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.PillarAssembly).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.PillarRackSlot).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.InfusionId).SetIgnoreIfNull(true);

                    cm.MapMember(c => c.PatientId).SetIgnoreIfNull(true);
                    
                    cm.MapMember(c => c.LastUpdated).SetIgnoreIfNull(true);

                    // Estado
                    cm.MapMember(c => c.IsInfusing).SetIgnoreIfNull(true);

                    cm.MapMember(c => c.InfusingStatus)
                      .SetIgnoreIfNull(true)
                      .SetSerializer(new NullableSerializer<PumpEnum.InfusingStatus>(
                          new EnumSerializer<PumpEnum.InfusingStatus>(BsonType.String)));

                    cm.MapMember(c => c.Status)
                      .SetIgnoreIfNull(true)
                      .SetSerializer(new NullableSerializer<PumpEnum.Status>(
                          new EnumSerializer<PumpEnum.Status>(BsonType.String)));

                    cm.MapMember(c => c.PumpMode)
                      .SetIgnoreIfNull(true)
                      .SetSerializer(new NullableSerializer<PumpEnum.Mode>(
                          new EnumSerializer<PumpEnum.Mode>(BsonType.String)));

                    cm.MapMember(c => c.InfusionModeDetail).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.ActiveSourceInfo).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.NotDeliveringReason).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Source).SetIgnoreIfNull(true);

                    // Métricas
                    cm.MapMember(c => c.FlowFluid).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Rate).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.VolumeInfused).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.FluidDelivTotal).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.FluidDelivTotalSet).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.VolumeRemaining).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Vtbi).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.TimeRemaining).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.TimeProgrammed).SetIgnoreIfNull(true);

                    // Medicación
                    cm.MapMember(c => c.DrugName).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.DrugId).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Concentration).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.DoseRate).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.DrugAmount).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.DrugDoseDelivered).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.PatientWeight).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Syringe).SetIgnoreIfNull(true);

                    // Última alarma resumen
                    cm.MapMember(c => c.AlarmType)
                      .SetIgnoreIfNull(true)
                      .SetSerializer(new NullableSerializer<PumpEnum.AlarmType>(
                          new EnumSerializer<PumpEnum.AlarmType>(BsonType.String)));

                    cm.MapMember(c => c.AlarmDescription).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.AlarmState).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.AlarmInactivationState).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.AlarmPriority).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.AlarmCodeMdc).SetIgnoreIfNull(true);

                    cm.MapMember(c => c.Event)
                      .SetIgnoreIfNull(true)
                      .SetSerializer(new NullableSerializer<PumpEnum.Event>(
                          new EnumSerializer<PumpEnum.Event>(BsonType.String)));

                    cm.MapMember(c => c.EventPhase)
                      .SetIgnoreIfNull(true)
                      .SetSerializer(new NullableSerializer<PumpEnum.EventPhase>(
                          new EnumSerializer<PumpEnum.EventPhase>(BsonType.String)));

                    // Relay / Comm
                    cm.MapMember(c => c.CommStatus).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.RelayState).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.RelayGuid).SetIgnoreIfNull(true);
                });
            }

            // ============================================================
            // PumpAlarmEvent
            // ============================================================
            if (!BsonClassMap.IsClassMapRegistered(typeof(PumpAlarmEvent)))
            {
                BsonClassMap.RegisterClassMap<PumpAlarmEvent>(cm =>
                {
                    cm.AutoMap();
                    cm.MapIdMember(c => c.Id).SetElementName("_id");

                    cm.MapMember(c => c.DeviceId).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.RackId).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.DeviceTypeMdc).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.InfusionId).SetIgnoreIfNull(true);

                    cm.MapMember(c => c.PatientId).SetIgnoreIfNull(true);
                    
                    cm.MapMember(c => c.Time).SetIgnoreIfNull(true);

                    cm.MapMember(c => c.AlarmType)
                      .SetIgnoreIfNull(true)
                      .SetSerializer(new NullableSerializer<PumpEnum.AlarmType>(
                          new EnumSerializer<PumpEnum.AlarmType>(BsonType.String)));

                    cm.MapMember(c => c.AlarmDescription).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.AlarmState).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.AlarmInactivationState).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.AlarmPriority).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.AlarmTypeMdc).SetIgnoreIfNull(true);

                    cm.MapMember(c => c.EventPhase)
                      .SetIgnoreIfNull(true)
                      .SetSerializer(new NullableSerializer<PumpEnum.EventPhase>(
                          new EnumSerializer<PumpEnum.EventPhase>(BsonType.String)));

                    cm.MapMember(c => c.AlertSourceMdc).SetIgnoreIfNull(true);

                    cm.MapMember(c => c.DeviceIp).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.PillarAssembly).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.PillarRackSlot).SetIgnoreIfNull(true);
                });
            }

            // ============================================================
            // PumpAlarmState
            // ============================================================
            if (!BsonClassMap.IsClassMapRegistered(typeof(PumpAlarmState)))
            {
                BsonClassMap.RegisterClassMap<PumpAlarmState>(cm =>
                {
                    cm.AutoMap();
                    cm.MapIdMember(c => c.Id).SetElementName("_id");

                    cm.MapMember(c => c.DeviceId).SetIgnoreIfNull(true);

                    cm.MapMember(c => c.PatientId).SetIgnoreIfNull(true);
                    
                    cm.MapMember(c => c.AlarmType)
                      .SetIgnoreIfNull(true)
                      .SetSerializer(new NullableSerializer<PumpEnum.AlarmType>(
                          new EnumSerializer<PumpEnum.AlarmType>(BsonType.String)));

                    cm.MapMember(c => c.AlarmCodeMdc).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.AlarmDescription).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.AlarmPriority).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.AlarmState).SetIgnoreIfNull(true);

                    cm.MapMember(c => c.LastPhase)
                      .SetIgnoreIfNull(true)
                      .SetSerializer(new NullableSerializer<PumpEnum.EventPhase>(
                          new EnumSerializer<PumpEnum.EventPhase>(BsonType.String)));

                    cm.MapMember(c => c.FirstSeen).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.LastUpdated).SetIgnoreIfNull(true);

                    cm.MapMember(c => c.AlertSourceMdc).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.InfusionId).SetIgnoreIfNull(true);
                });
            }
           
            // ============================================================
            // ConfigPumps
            // ============================================================
            if (!BsonClassMap.IsClassMapRegistered(typeof(ConfigPumps)))
            {
                BsonClassMap.RegisterClassMap<ConfigPumps>(cm =>
                {
                    cm.AutoMap();
                    cm.MapIdMember(c => c.Id).SetElementName("_id");
                    cm.MapMember(c => c.Items).SetIgnoreIfNull(true);
                    
                });
            }
            
            // ============================================================
            // ConfigPumpItem
            // ============================================================
            if (!BsonClassMap.IsClassMapRegistered(typeof(ConfigPumpItem)))
            {
                BsonClassMap.RegisterClassMap<ConfigPumpItem>(cm =>
                {
                    cm.AutoMap();
                    cm.MapMember(c => c.AlarmType)
                        .SetIgnoreIfNull(true)
                        .SetSerializer(new NullableSerializer<PumpEnum.AlarmType>(
                            new EnumSerializer<PumpEnum.AlarmType>(BsonType.String)));
                    cm.MapMember(c => c.UiConfiguration).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Type)
                        .SetIgnoreIfNull(true)
                        .SetSerializer(new NullableSerializer<PumpEnum.PumpMessageType>(
                            new EnumSerializer<PumpEnum.PumpMessageType>(BsonType.String)));
                    cm.MapMember(c => c.RetentionPolicy).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.RetentionPolicyValue).SetIgnoreIfNull(true);
                });
            }
            
            
        }
    }
}