using Baya.Domain.Entities.Catalog;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Baya.Infrastructure.Persistence.Configuration.CatalogConfig;

internal sealed class NurseServiceVariantConfig : IEntityTypeConfiguration<NurseServiceVariant>
{
    public void Configure(EntityTypeBuilder<NurseServiceVariant> builder)
    {
        builder.ToTable("NurseServiceVariants", "catalog");

        // Price is IRR Rials as BIGINT (long → bigint). There is no float/decimal money path, ever.
        builder.Property(v => v.PriceUnit).HasMaxLength(20).IsRequired();
        builder.Property(v => v.DisplayName).HasMaxLength(300).IsRequired();
        builder.Property(v => v.OptionSetHash).HasMaxLength(64).IsRequired();
        builder.Property(v => v.IsActive).HasDefaultValue(true);

        // The nurse's offerings list + the b7 index projection read on (nurse_id, is_active).
        builder.HasIndex(v => new { v.NurseId, v.IsActive });
        // Leading column is nurse_id on the unique index, so a standalone category index is still useful
        // for "all variants in a category" (b7 category browse).
        builder.HasIndex(v => v.ServiceCategoryId);

        // Duplicate-listing DB backstop: a multi-row option-set can't be a plain composite unique, so it is
        // reduced to a deterministic option_set_hash and made race-safe here. Filtered to exclude
        // soft-deleted rows so a deactivated+deleted listing can be re-created.
        builder.HasIndex(v => new { v.NurseId, v.ServiceCategoryId, v.OptionSetHash })
            .IsUnique()
            .HasFilter("[DeletedAt] IS NULL")
            .HasDatabaseName("UX_NurseServiceVariants_Nurse_Category_OptionSet");

        builder.HasOne(v => v.Nurse)
            .WithMany()
            .HasForeignKey(v => v.NurseId)
            .IsRequired();

        builder.HasOne(v => v.ServiceCategory)
            .WithMany(c => c.Variants)
            .HasForeignKey(v => v.ServiceCategoryId)
            .IsRequired();

        builder.HasQueryFilter(v => v.DeletedAt == null);
    }
}
