using ERPCore.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace ERPCore.Infra.Persistence.Configurations;

public sealed class SalesDayEndConfiguration : IEntityTypeConfiguration<SalesDayEnd>
{
    public void Configure(EntityTypeBuilder<SalesDayEnd> builder)
    {
        builder.ToTable("sales_day_ends");
        builder.HasKey(x => x.SalesDayEndId);

        builder.Property(x => x.DocNo).IsRequired().HasMaxLength(30);
        builder.HasIndex(x => x.DocNo).IsUnique();

        builder.Property(x => x.BusinessDate).IsRequired();

        foreach (var p in new[] { nameof(SalesDayEnd.Subtotal), nameof(SalesDayEnd.DiscountTotal), nameof(SalesDayEnd.TaxTotal), nameof(SalesDayEnd.GrandTotal), nameof(SalesDayEnd.CostOfGoodsSold) })
            builder.Property<decimal>(p).HasPrecision(18, 4);
        builder.Property(x => x.BundleCount).HasDefaultValue(0);

        builder.Property(x => x.GlJournalNo).HasMaxLength(30);
        builder.Property(x => x.ClosedAt).IsRequired();
        builder.Property(x => x.RowVersion).IsRowVersion();

        builder.HasOne(x => x.CashierUser).WithMany().HasForeignKey(x => x.CashierUserId).OnDelete(DeleteBehavior.Restrict);
        builder.HasOne(x => x.ClosedByUser).WithMany().HasForeignKey(x => x.ClosedBy).OnDelete(DeleteBehavior.Restrict);

        // A cashier can only close a given business date once (CloseAsync replays this
        // row idempotently on a second call instead of erroring — see SalesDayEndService).
        builder.HasIndex(x => new { x.CashierUserId, x.BusinessDate }).IsUnique();

        builder.HasMany(x => x.Slips)
            .WithOne(x => x.DayEnd)
            .HasForeignKey(x => x.DayEndId)
            .OnDelete(DeleteBehavior.Restrict);

        builder.HasMany(x => x.BundleSales)
            .WithOne(x => x.DayEnd)
            .HasForeignKey(x => x.DayEndId)
            .OnDelete(DeleteBehavior.Restrict);
    }
}
