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>
/// Provides card-specific mapping contributions by implementing the <see cref="IEntityMapContributor"/> contract within the entity mapping pipeline.
/// </summary>
public class CardMapContributor : IEntityMapContributor
{
    /// <summary>
    /// Registers BSON class maps for the layout and configuration types used by the display configuration domain, including <see cref="SectionBoxLayout"/>, <see cref="CardDetailsConfig"/>, <see cref="CardRotatingLayout"/>, <see cref="Step"/>, and <see cref="HomeConfig"/>. Each map is only registered when no existing map is present, and the configuration establishes default values, enum-as-string serialization, and ignore-if-null behavior for nullable layout properties.
    /// </summary>
    public void RegisterMaps()
        {
            if (!BsonClassMap.IsClassMapRegistered(typeof(SectionBoxLayout)))
                BsonClassMap.RegisterClassMap<SectionBoxLayout>(cm =>
                {
                    cm.AutoMap();
                    cm.MapMember(c => c.Type).SetDefaultValue(DisplayConfigEnums.RowType.Simple)
                        .SetSerializer(new EnumSerializer<DisplayConfigEnums.RowType>(BsonType.String));
                    cm.MapMember(c => c.Name).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Subtitle).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Icon).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.GridColumn).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.PaddingTop).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.PaddingBottom).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.PaddingLeft).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.PaddingRight).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.BorderColor).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.BorderWidth).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.BorderStyle).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.BorderRadius).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.HProportion).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.BgColor).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.SectionUrl).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.MinHeight).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Subtitle).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Conditions).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Direction).SetDefaultValue(DisplayConfigEnums.DirectionEnum.Row)
                        .SetSerializer(new EnumSerializer<DisplayConfigEnums.DirectionEnum>(BsonType.String));
                    cm.MapMember(c => c.Rows).SetDefaultValue(new List<RowBoxLayout>());
                });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(CardDetailsConfig)))
                BsonClassMap.RegisterClassMap<CardDetailsConfig>(cm =>
                {
                    cm.AutoMap();
                    cm.MapIdMember(c => c.Id).SetElementName("_id");
                    cm.MapMember(c => c.Header).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.SmartSections).SetDefaultValue(new List<SectionBoxLayout>());
                    cm.MapMember(c => c.NurseRows).SetDefaultValue(new List<RowDetailsConfig>());
                });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(CardRotatingLayout)))
                BsonClassMap.RegisterClassMap<CardRotatingLayout>(cm =>
                {
                    cm.AutoMap();
                    cm.MapMember(c => c.MillisecondsBeforeRotating).SetDefaultValue(3000);
                    cm.MapMember(c => c.Order).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Name).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Title).SetIgnoreIfNull(true);
                    cm.MapMember(c => c.Data)
                        .SetIgnoreIfNull(true)
                        .SetIsRequired(false);
                    cm.MapMember(c => c.Type).SetDefaultValue(DisplayConfigEnums.RotatingLayoutType.HomeSection)
                        .SetSerializer(new EnumSerializer<DisplayConfigEnums.RotatingLayoutType>(BsonType.String));
                    cm.MapMember(c => c.Mode).SetDefaultValue(DisplayConfigEnums.RotatingLayoutMode.Default)
                        .SetSerializer(new EnumSerializer<DisplayConfigEnums.RotatingLayoutMode>(BsonType.String));
                });
    
            //standard card rotating layout
            if (!BsonClassMap.IsClassMapRegistered(typeof(Step)))
                BsonClassMap.RegisterClassMap<Step>(cm =>
                {
                    cm.AutoMap();
                    cm.MapMember(c => c.Type)
                        .SetIgnoreIfNull(true)
                        .SetSerializer(
                            new NullableSerializer<DisplayConfigEnums.StepType>(
                                new EnumSerializer<DisplayConfigEnums.StepType>(BsonType.String)));
                });
    
            if (!BsonClassMap.IsClassMapRegistered(typeof(HomeConfig)))
                BsonClassMap.RegisterClassMap<HomeConfig>(cm =>
                {
                    cm.AutoMap();
                    cm.MapMember(c => c.MinColumnSize).SetDefaultValue("250");
                    cm.MapMember(c => c.ColumnsPerBreakpoint).SetDefaultValue(1);
                    cm.MapMember(c => c.BreakpointSize).SetDefaultValue("2000");
                    cm.MapMember(c => c.CardAspectRatioHeight).SetDefaultValue("700");
                    cm.MapMember(c => c.CardAspectRatioWidth).SetDefaultValue("500");
                });
        }
}