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

namespace ERPCore.Infra.Persistence.Configurations;

public sealed class EmployeeConfiguration : IEntityTypeConfiguration<Employee>
{
    public void Configure(EntityTypeBuilder<Employee> builder)
    {
        builder.ToTable("hr_employees");
        builder.HasKey(e => e.EmployeeId);

        builder.Property(e => e.EmployeeCode).IsRequired().HasMaxLength(30);
        builder.HasIndex(e => e.EmployeeCode).IsUnique();

        builder.Property(e => e.FullName).IsRequired().HasMaxLength(200);
        builder.Property(e => e.Nic).HasMaxLength(30);
        builder.Property(e => e.Nationality).HasMaxLength(100);
        builder.Property(e => e.ProfilePhotoPath).HasMaxLength(500);
        builder.Property(e => e.Gender).HasConversion<string>().HasMaxLength(20);

        builder.Property(e => e.Email).HasMaxLength(320);
        builder.HasIndex(e => e.Email);
        builder.Property(e => e.PersonalMobile).HasMaxLength(30);
        builder.Property(e => e.AddressLine1).HasMaxLength(200);
        builder.Property(e => e.AddressLine2).HasMaxLength(200);
        builder.Property(e => e.City).HasMaxLength(100);
        builder.Property(e => e.PostalCode).HasMaxLength(20);
        builder.Property(e => e.Country).HasMaxLength(100);

        builder.Property(e => e.EmergencyContactName).HasMaxLength(200);
        builder.Property(e => e.EmergencyContactRelationship).HasMaxLength(100);
        builder.Property(e => e.EmergencyContactPhone).HasMaxLength(30);

        builder.Property(e => e.EpfNumber).HasMaxLength(30);
        builder.Property(e => e.EtfNumber).HasMaxLength(30);
        builder.Property(e => e.TaxIdentificationNumber).HasMaxLength(30);

        builder.HasOne(e => e.Department).WithMany()
            .HasForeignKey(e => e.DepartmentId).OnDelete(DeleteBehavior.Restrict);
        builder.HasOne(e => e.Designation).WithMany()
            .HasForeignKey(e => e.DesignationId).OnDelete(DeleteBehavior.Restrict);
        builder.HasOne(e => e.EmploymentType).WithMany()
            .HasForeignKey(e => e.EmploymentTypeId).OnDelete(DeleteBehavior.Restrict);
        builder.HasOne(e => e.Branch).WithMany()
            .HasForeignKey(e => e.BranchId).OnDelete(DeleteBehavior.Restrict);
        builder.HasOne(e => e.WorkShift).WithMany()
            .HasForeignKey(e => e.WorkShiftId).OnDelete(DeleteBehavior.Restrict);
        builder.HasOne(e => e.ReportingManager).WithMany()
            .HasForeignKey(e => e.ReportingManagerId).OnDelete(DeleteBehavior.Restrict);

        // One User backs at most one Employee (docs/12-BACKEND-HRM.md A.5/C.2).
        // Postgres unique indexes allow multiple NULLs natively, so no explicit
        // filter is needed (same pattern as User.AuthUserId).
        builder.HasOne(e => e.User).WithOne()
            .HasForeignKey<Employee>(e => e.UserId).OnDelete(DeleteBehavior.Restrict);
        builder.HasIndex(e => e.UserId).IsUnique();

        builder.Property(e => e.Status)
            .HasConversion<string>().HasMaxLength(20).IsRequired()
            .HasDefaultValue(EmployeeStatus.Active);

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

        builder.HasIndex(e => e.Status);
        builder.HasIndex(e => e.DepartmentId);
    }
}
