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

namespace ERPCore.Infra.Persistence.Configurations;

public sealed class SalesSlipConfiguration : IEntityTypeConfiguration<SalesSlip>
{
    public void Configure(EntityTypeBuilder<SalesSlip> builder)
    {
        builder.ToTable("sales_slips");
        builder.HasKey(x => x.SalesSlipId);

        builder.Property(x => x.SlipNo).IsRequired().HasMaxLength(50);
        builder.HasIndex(x => x.SlipNo).IsUnique();

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

        builder.HasOne(x => x.Customer)
            .WithMany()
            .HasForeignKey(x => x.CustomerId)
            .OnDelete(DeleteBehavior.Restrict);

        builder.Property(x => x.CustomerSnapshotName).IsRequired().HasMaxLength(200);

        builder.HasOne(x => x.Warehouse)
            .WithMany()
            .HasForeignKey(x => x.WarehouseId)
            .OnDelete(DeleteBehavior.Restrict);

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

        builder.Property(x => x.Status)
            .HasConversion<string>().HasMaxLength(20).IsRequired()
            .HasDefaultValue(SalesSlipStatus.Draft);

        foreach (var p in new[] { nameof(SalesSlip.Subtotal), nameof(SalesSlip.DiscountTotal), nameof(SalesSlip.TaxTotal), nameof(SalesSlip.GrandTotal), nameof(SalesSlip.PaidAmount), nameof(SalesSlip.BalanceAmount) })
            builder.Property<decimal>(p).HasPrecision(18, 4);

        builder.Property(x => x.CreatedAt).IsRequired();
        builder.Property(x => x.RowVersion).IsRowVersion();

        builder.HasIndex(x => x.Status);
        builder.HasIndex(x => x.SlipDate);

        builder.HasMany(x => x.Lines)
            .WithOne(x => x.SalesSlip)
            .HasForeignKey(x => x.SalesSlipId)
            .OnDelete(DeleteBehavior.Cascade);
    }
}

public sealed class SalesSlipLineConfiguration : IEntityTypeConfiguration<SalesSlipLine>
{
    public void Configure(EntityTypeBuilder<SalesSlipLine> builder)
    {
        builder.ToTable("sales_slip_lines");
        builder.HasKey(x => x.SalesSlipLineId);

        builder.HasOne(x => x.Item)
            .WithMany()
            .HasForeignKey(x => x.ItemId)
            .OnDelete(DeleteBehavior.Restrict);

        builder.Property(x => x.Description).IsRequired().HasMaxLength(200);

        builder.Property(x => x.Qty).HasPrecision(18, 4);
        builder.Property(x => x.FreeQty).HasPrecision(18, 4);
        builder.Property(x => x.UnitPrice).HasPrecision(18, 4);
        builder.Property(x => x.BaseCost).HasPrecision(18, 4);
        builder.Property(x => x.DiscountPct).HasPrecision(9, 4);
        builder.Property(x => x.DiscountAmount).HasPrecision(18, 4);
        builder.Property(x => x.NetUnitPrice).HasPrecision(18, 4);
        builder.Property(x => x.LineTotal).HasPrecision(18, 4);
        builder.Property(x => x.TaxPct).HasPrecision(9, 4);
        builder.Property(x => x.TaxAmount).HasPrecision(18, 4);

        builder.HasOne(x => x.Warehouse)
            .WithMany()
            .HasForeignKey(x => x.WarehouseId)
            .OnDelete(DeleteBehavior.Restrict);

        builder.Property(x => x.PriceSource).HasMaxLength(50);
        builder.Property(x => x.RowVersion).IsRowVersion();
    }
}
