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

namespace Baya.Infrastructure.Persistence.Configuration.RefundsConfig;

/// <summary>
/// <c>nurse_clawbacks</c> — a first-class receivable opened when a booking is refunded after the nurse was
/// already paid. <c>original_payout_id</c> / <c>recovered_in_payout_id</c> are nullable FKs to
/// <c>payouts.NursePayouts</c> (b13 shipped the table and sets the values; refinement-phase-6 added the
/// constraints, <c>ON DELETE NO ACTION</c>).
/// </summary>
internal sealed class NurseClawbackConfig : IEntityTypeConfiguration<NurseClawback>
{
    public void Configure(EntityTypeBuilder<NurseClawback> builder)
    {
        builder.ToTable("NurseClawbacks", "payments");

        builder.Property(c => c.Status).HasMaxLength(30).IsRequired();
        builder.Property(c => c.ResolutionNotes).HasMaxLength(500);

        builder.HasIndex(c => c.NurseId);
        builder.HasIndex(c => c.BookingId);
        builder.HasIndex(c => c.RefundId).IsUnique();
        builder.HasIndex(c => c.Status);
        builder.HasIndex(c => c.OriginalPayoutId);
        builder.HasIndex(c => c.RecoveredInPayoutId);

        builder.HasOne<NurseProfile>().WithMany().HasForeignKey(c => c.NurseId).IsRequired();
        builder.HasOne<Booking>().WithMany().HasForeignKey(c => c.BookingId).IsRequired();
        builder.HasOne<Refund>().WithMany().HasForeignKey(c => c.RefundId).IsRequired();
        // Forward-dep FKs to the b13 payouts table (refinement-phase-6). Both optional (nullable); NO ACTION so
        // deleting a payout never cascades into the receivable rows. Two distinct FKs to the same principal.
        builder.HasOne<NursePayout>().WithMany().HasForeignKey(c => c.OriginalPayoutId).OnDelete(DeleteBehavior.NoAction);
        builder.HasOne<NursePayout>().WithMany().HasForeignKey(c => c.RecoveredInPayoutId).OnDelete(DeleteBehavior.NoAction);

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