using Baya.Domain.Entities.Booking;
using Baya.Domain.Entities.Identity;
using Baya.Domain.Entities.Reviews;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Baya.Infrastructure.Persistence.Configuration.ReviewsConfig;

/// <summary>
/// <c>reviews</c> — one review per completed booking. The <c>UNIQUE(booking_id)</c> is the authoritative 1:1
/// backstop; <c>CHECK(rating BETWEEN 1 AND 5)</c> guards the score. Only <c>published</c> reviews are public
/// or counted in the nurse aggregate — the <c>(nurse_profile_id, moderation_status)</c> index serves both the
/// public list and the recompute; the <c>moderation_status</c> index serves the moderation queue.
/// </summary>
internal sealed class ReviewConfig : IEntityTypeConfiguration<Review>
{
    public void Configure(EntityTypeBuilder<Review> builder)
    {
        builder.ToTable("Reviews", "reviews", t => t.HasCheckConstraint(
            "CK_Reviews_Rating", "[Rating] BETWEEN 1 AND 5"));

        builder.Property(r => r.Rating).IsRequired();
        builder.Property(r => r.Body).HasMaxLength(2000);
        builder.Property(r => r.ModerationStatus).HasMaxLength(30).IsRequired();
        builder.Property(r => r.ModerationReason).HasMaxLength(500);

        builder.HasIndex(r => r.BookingId).IsUnique();
        builder.HasIndex(r => new { r.NurseProfileId, r.ModerationStatus });
        builder.HasIndex(r => r.ModerationStatus);

        builder.HasOne<Booking>().WithMany().HasForeignKey(r => r.BookingId).IsRequired();
        builder.HasOne<CustomerProfile>().WithMany().HasForeignKey(r => r.CustomerProfileId).IsRequired();
        builder.HasOne<NurseProfile>().WithMany().HasForeignKey(r => r.NurseProfileId).IsRequired();

        builder.HasMany(r => r.TagLinks).WithOne(l => l.Review).HasForeignKey(l => l.ReviewId).IsRequired();

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