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

namespace ERPCore.Infra.Persistence.Configurations;

public sealed class PayrollLineConfiguration : IEntityTypeConfiguration<PayrollLine>
{
    public void Configure(EntityTypeBuilder<PayrollLine> builder)
    {
        builder.ToTable("hr_payroll_lines");
        builder.HasKey(l => l.PayrollLineId);

        foreach (var money in new[]
        {
            nameof(PayrollLine.BasicSalary), nameof(PayrollLine.TotalAllowances), nameof(PayrollLine.OvertimeAmount),
            nameof(PayrollLine.GrossSalary), nameof(PayrollLine.LateDeductionAmount), nameof(PayrollLine.NoPayAmount),
            nameof(PayrollLine.LoanDeductionAmount), nameof(PayrollLine.EpfEmployeeAmount), nameof(PayrollLine.EpfEmployerAmount),
            nameof(PayrollLine.EtfEmployerAmount), nameof(PayrollLine.TaxAmount), nameof(PayrollLine.OtherDeductionsAmount),
            nameof(PayrollLine.NetSalary)
        })
        {
            builder.Property(money).HasColumnType("numeric(18,2)");
        }

        builder.HasOne(l => l.Employee).WithMany()
            .HasForeignKey(l => l.EmployeeId).OnDelete(DeleteBehavior.Restrict);

        builder.HasMany(l => l.Components).WithOne(c => c.PayrollLine!)
            .HasForeignKey(c => c.PayrollLineId).OnDelete(DeleteBehavior.Cascade);

        builder.Property(l => l.RowVersion).IsRowVersion();

        builder.HasIndex(l => new { l.PayrollRunId, l.EmployeeId }).IsUnique();
    }
}

public sealed class PayrollLineComponentConfiguration : IEntityTypeConfiguration<PayrollLineComponent>
{
    public void Configure(EntityTypeBuilder<PayrollLineComponent> builder)
    {
        builder.ToTable("hr_payroll_line_components");
        builder.HasKey(c => c.PayrollLineComponentId);

        builder.Property(c => c.ComponentCategory).HasConversion<string>().HasMaxLength(20).IsRequired();
        builder.Property(c => c.Label).IsRequired().HasMaxLength(200);
        builder.Property(c => c.Amount).HasPrecision(18, 2);

        builder.HasOne(c => c.SalaryComponent).WithMany()
            .HasForeignKey(c => c.SalaryComponentId).OnDelete(DeleteBehavior.Restrict);
    }
}
