using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using IamService.Domain.AggregatesModel.UserAggregate;

namespace IamService.Infrastructure.EntityConfigurations;

/// <summary>
/// EN: Entity configuration for UserProfile.
/// VI: Cấu hình entity cho UserProfile.
/// </summary>
public class UserProfileEntityConfiguration : IEntityTypeConfiguration<UserProfile>
{
    public void Configure(EntityTypeBuilder<UserProfile> builder)
    {
        builder.ToTable("user_profiles");

        builder.HasKey(p => p.Id);

        builder.Property(p => p.Id)
            .HasColumnName("id")
            .ValueGeneratedNever();

        builder.Property("_userId")
            .HasColumnName("user_id")
            .IsRequired();

        // EN: Unique index - one profile per user
        // VI: Unique index - mỗi user một profile
        builder.HasIndex("_userId")
            .IsUnique()
            .HasDatabaseName("ix_user_profiles_user_id");

        builder.Property("_bio")
            .HasColumnName("bio")
            .HasMaxLength(2000);

        builder.Property("_avatarUrl")
            .HasColumnName("avatar_url")
            .HasMaxLength(500);

        builder.Property("_timezone")
            .HasColumnName("timezone")
            .HasMaxLength(50);

        builder.Property("_locale")
            .HasColumnName("locale")
            .HasMaxLength(10);

        builder.Property("_dateOfBirth")
            .HasColumnName("date_of_birth");

        builder.Property("_createdAt")
            .HasColumnName("created_at")
            .IsRequired();

        builder.Property("_updatedAt")
            .HasColumnName("updated_at");

        // EN: Configure owned entity for PhoneNumber
        // VI: Cấu hình owned entity cho PhoneNumber
        builder.OwnsOne<PhoneNumber>("_phoneNumber", phone =>
        {
            phone.Property(p => p.CountryCode)
                .HasColumnName("phone_country_code")
                .HasMaxLength(5);

            phone.Property(p => p.NationalNumber)
                .HasColumnName("phone_national_number")
                .HasMaxLength(15);
        });

        // EN: Configure owned entity for Address
        // VI: Cấu hình owned entity cho Address
        builder.OwnsOne<Address>("_address", address =>
        {
            address.Property(a => a.Street)
                .HasColumnName("address_street")
                .HasMaxLength(200);

            address.Property(a => a.Street2)
                .HasColumnName("address_street2")
                .HasMaxLength(200);

            address.Property(a => a.City)
                .HasColumnName("address_city")
                .HasMaxLength(100);

            address.Property(a => a.State)
                .HasColumnName("address_state")
                .HasMaxLength(100);

            address.Property(a => a.PostalCode)
                .HasColumnName("address_postal_code")
                .HasMaxLength(20);

            address.Property(a => a.Country)
                .HasColumnName("address_country")
                .HasMaxLength(2);  // ISO 3166-1 alpha-2
        });

        // EN: Configure navigation to attributes
        // VI: Cấu hình navigation đến attributes
        builder.HasMany(p => p.Attributes)
            .WithOne()
            .HasForeignKey("_userProfileId")
            .OnDelete(DeleteBehavior.Cascade);
    }
}

/// <summary>
/// EN: Entity configuration for ProfileAttribute.
/// VI: Cấu hình entity cho ProfileAttribute.
/// </summary>
public class ProfileAttributeEntityConfiguration : IEntityTypeConfiguration<ProfileAttribute>
{
    public void Configure(EntityTypeBuilder<ProfileAttribute> builder)
    {
        builder.ToTable("profile_attributes");

        builder.HasKey(a => a.Id);

        builder.Property(a => a.Id)
            .HasColumnName("id")
            .ValueGeneratedNever();

        builder.Property("_userProfileId")
            .HasColumnName("user_profile_id")
            .IsRequired();

        builder.Property("_key")
            .HasColumnName("key")
            .HasMaxLength(100)
            .IsRequired();

        builder.Property("_value")
            .HasColumnName("value")
            .HasMaxLength(4000)
            .IsRequired();

        builder.Property(a => a.ValueTypeId)
            .HasColumnName("value_type_id")
            .IsRequired();

        builder.Property("_createdAt")
            .HasColumnName("created_at")
            .IsRequired();

        builder.Property("_updatedAt")
            .HasColumnName("updated_at");

        // EN: Unique index - one key per profile
        // VI: Unique index - mỗi key cho mỗi profile
        builder.HasIndex("_userProfileId", "_key")
            .IsUnique()
            .HasDatabaseName("ix_profile_attributes_profile_key");

        // EN: Ignore expression-bodied properties
        // VI: Bỏ qua properties expression-bodied
        builder.Ignore(a => a.UserProfileId);
        builder.Ignore(a => a.Key);
        builder.Ignore(a => a.Value);
        builder.Ignore(a => a.ValueType);
        builder.Ignore(a => a.CreatedAt);
        builder.Ignore(a => a.UpdatedAt);
    }
}

/// <summary>
/// EN: Entity configuration for ProfileAttributeType.
/// VI: Cấu hình entity cho ProfileAttributeType.
/// </summary>
public class ProfileAttributeTypeEntityConfiguration : IEntityTypeConfiguration<ProfileAttributeType>
{
    public void Configure(EntityTypeBuilder<ProfileAttributeType> builder)
    {
        builder.ToTable("profile_attribute_types");

        builder.HasKey(t => t.Id);

        builder.Property(t => t.Id)
            .HasColumnName("id")
            .ValueGeneratedNever();

        builder.Property(t => t.Name)
            .HasColumnName("name")
            .HasMaxLength(50)
            .IsRequired();

        // EN: Seed data
        // VI: Seed data
        builder.HasData(
            ProfileAttributeType.String,
            ProfileAttributeType.Number,
            ProfileAttributeType.Boolean,
            ProfileAttributeType.Date,
            ProfileAttributeType.Json
        );
    }
}
