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

namespace Baya.Infrastructure.Persistence.Configuration.PayoutsConfig;

/// <summary>
/// <c>nurse_payouts</c> — one row per nurse per batch. The <c>net = gross − clawback</c> decomposition + all
/// amounts non-negative + <c>net ≥ 0</c> (never a negative transfer) is a DB CHECK mirroring b9/b11.
/// <c>iban_snapshot</c> is encrypted at rest (converter wired in <c>ApplicationDbContext</c>) and frozen at build
/// time from the nurse's verified primary account. Paid-ness is derived from a link row + the ledger — there is
/// no boolean flag. N:1 → batch / nurse_profiles / nurse_bank_accounts; 1:N → links.
/// </summary>
internal sealed class NursePayoutConfig : IEntityTypeConfiguration<NursePayout>
{
    public void Configure(EntityTypeBuilder<NursePayout> builder)
    {
        builder.ToTable("NursePayouts", "payouts", t => t.HasCheckConstraint(
            "CK_NursePayouts_NetSplit",
            "[NetAmountIrr] = [GrossEarningsIrr] - [ClawbackAppliedIrr] " +
            "AND [GrossEarningsIrr] >= 0 AND [ClawbackAppliedIrr] >= 0 AND [NetAmountIrr] >= 0 AND [Amount] >= 0"));

        builder.Property(p => p.IbanSnapshot).IsRequired();
        builder.Property(p => p.Status).HasMaxLength(20).IsRequired();
        builder.Property(p => p.TransferReference).HasMaxLength(200);
        builder.Property(p => p.FailureReason).HasMaxLength(500);

        builder.HasIndex(p => p.BatchId);
        builder.HasIndex(p => p.NurseId);
        builder.HasIndex(p => p.Status);

        builder.HasMany(p => p.BookingLinks).WithOne().HasForeignKey(l => l.PayoutId).IsRequired();

        builder.HasOne<NurseProfile>().WithMany().HasForeignKey(p => p.NurseId).IsRequired();
        builder.HasOne<NurseBankAccount>().WithMany().HasForeignKey(p => p.BankAccountId).IsRequired();

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