using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

public class PatientConfiguration : IEntityTypeConfiguration<Patient>
{
    public void Configure(EntityTypeBuilder<Patient> builder)
    {
        builder.ToTable("patients");
        builder.HasKey(p => p.Id);
        builder.Property(p => p.Id).HasColumnName("id").HasDefaultValueSql("gen_random_uuid()");
        builder.Property(p => p.Mrn).HasColumnName("mrn").HasMaxLength(20).IsRequired();
        builder.Property(p => p.FirstName).HasColumnName("first_name").HasMaxLength(100).IsRequired();
        builder.Property(p => p.LastName).HasColumnName("last_name").HasMaxLength(100).IsRequired();
        builder.Property(p => p.DateOfBirth).HasColumnName("date_of_birth");
        builder.Property(p => p.Gender).HasColumnName("gender").HasMaxLength(10).IsRequired();
        builder.Property(p => p.Status).HasColumnName("status").HasMaxLength(20).HasDefaultValue("active");
        builder.Property(p => p.BloodType).HasColumnName("blood_type").HasMaxLength(5)
            .HasConversion(
                v => v!.Value.ToDbString(),
                v => BloodTypeExtensions.FromDbString(v));
        builder.Property(p => p.Allergies).HasColumnName("allergies");
        builder.Property(p => p.EmergencyContactName).HasColumnName("emergency_contact_name").HasMaxLength(200);
        builder.Property(p => p.EmergencyContactPhone).HasColumnName("emergency_contact_phone").HasMaxLength(20);
        builder.Property(p => p.NameSearchToken)
            .HasColumnName("name_search_token")
            .HasMaxLength(64);
        builder.Property(p => p.CreatedAt).HasColumnName("created_at").HasDefaultValueSql("NOW()");
        builder.Property(p => p.IsSimulated).HasColumnName("is_simulated").HasDefaultValue(false);

        // MRN uses exact-match unique index — MRN lookups are always equality checks,
        // never LIKE/ILIKE. A B-tree unique index satisfies O(log n) point lookup.
        // Name search uses ILIKE on first_name/last_name — a prefix scan, not an
        // equality match — so no index here; full ILIKE is intentionally unindexed
        // at this scale (pg_trgm GIN would be warranted at >500k patients).
        builder.HasIndex(p => p.Mrn).IsUnique();
        builder.HasIndex(p => p.NameSearchToken);
        // Filtered index keeps Phase 38 simulated-patient purge cheap.
        builder.HasIndex(p => p.IsSimulated)
            .HasDatabaseName("IX_Patients_IsSimulated")
            .HasFilter("is_simulated = true");
    }
}
