using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using SolutionErp.Domain.Contracts;

namespace SolutionErp.Infrastructure.Persistence.Configurations;

public class ContractConfiguration : IEntityTypeConfiguration<Contract>
{
    public void Configure(EntityTypeBuilder<Contract> b)
    {
        b.ToTable("Contracts");
        b.HasKey(x => x.Id);

        b.Property(x => x.MaHopDong).HasMaxLength(100);
        b.Property(x => x.Type).HasConversion<int>();
        b.Property(x => x.Phase).HasConversion<int>();
        b.Property(x => x.RejectedFromPhase).HasConversion<int?>();
        b.Property(x => x.GiaTri).HasPrecision(18, 2);
        b.Property(x => x.TenHopDong).HasMaxLength(500);
        b.Property(x => x.NoiDung).HasMaxLength(2000);
        b.Property(x => x.DraftData).HasColumnType("nvarchar(max)");
        b.Property(x => x.BudgetManualName).HasMaxLength(200);
        b.Property(x => x.BudgetManualAmount).HasPrecision(18, 2);

        b.HasIndex(x => x.MaHopDong).IsUnique().HasFilter("[MaHopDong] IS NOT NULL");
        b.HasIndex(x => new { x.Phase, x.IsDeleted });
        b.HasIndex(x => x.SupplierId);
        b.HasIndex(x => x.ProjectId);
        b.HasIndex(x => x.SlaDeadline);
        b.HasIndex(x => x.ApprovalWorkflowId);

        // FK ApprovalWorkflowId Restrict (Plan B Chunk A2 — Mig 32 mirror PE Mig 23)
        // ApprovalWorkflowsV2 pin lúc create HĐ V2. Restrict để KHÔNG xóa workflow
        // nếu còn HĐ pin.
        b.HasOne<SolutionErp.Domain.ApprovalWorkflowsV2.ApprovalWorkflow>()
            .WithMany()
            .HasForeignKey(x => x.ApprovalWorkflowId)
            .OnDelete(DeleteBehavior.Restrict);

        b.HasMany(x => x.Approvals).WithOne(a => a.Contract).HasForeignKey(a => a.ContractId).OnDelete(DeleteBehavior.Cascade);
        b.HasMany(x => x.Comments).WithOne(c => c.Contract).HasForeignKey(c => c.ContractId).OnDelete(DeleteBehavior.Cascade);
        b.HasMany(x => x.Attachments).WithOne(a => a.Contract).HasForeignKey(a => a.ContractId).OnDelete(DeleteBehavior.Cascade);

        b.HasQueryFilter(x => !x.IsDeleted);
    }
}

public class ContractApprovalConfiguration : IEntityTypeConfiguration<ContractApproval>
{
    public void Configure(EntityTypeBuilder<ContractApproval> b)
    {
        b.ToTable("ContractApprovals");
        b.HasKey(x => x.Id);

        b.Property(x => x.FromPhase).HasConversion<int>();
        b.Property(x => x.ToPhase).HasConversion<int>();
        b.Property(x => x.Decision).HasConversion<int>();
        b.Property(x => x.Comment).HasMaxLength(1000);

        b.HasIndex(x => new { x.ContractId, x.ApprovedAt });
    }
}

public class ContractCommentConfiguration : IEntityTypeConfiguration<ContractComment>
{
    public void Configure(EntityTypeBuilder<ContractComment> b)
    {
        b.ToTable("ContractComments");
        b.HasKey(x => x.Id);

        b.Property(x => x.Phase).HasConversion<int>();
        b.Property(x => x.Content).HasMaxLength(2000).IsRequired();

        b.HasIndex(x => new { x.ContractId, x.CreatedAt });
    }
}

public class ContractAttachmentConfiguration : IEntityTypeConfiguration<ContractAttachment>
{
    public void Configure(EntityTypeBuilder<ContractAttachment> b)
    {
        b.ToTable("ContractAttachments");
        b.HasKey(x => x.Id);

        b.Property(x => x.FileName).HasMaxLength(255).IsRequired();
        b.Property(x => x.StoragePath).HasMaxLength(500).IsRequired();
        b.Property(x => x.ContentType).HasMaxLength(100).IsRequired();
        b.Property(x => x.Purpose).HasConversion<int>();
        b.Property(x => x.Note).HasMaxLength(500);

        b.HasIndex(x => x.ContractId);
    }
}

public class ContractCodeSequenceConfiguration : IEntityTypeConfiguration<ContractCodeSequence>
{
    public void Configure(EntityTypeBuilder<ContractCodeSequence> b)
    {
        b.ToTable("ContractCodeSequences");
        b.HasKey(x => x.Prefix);
        b.Property(x => x.Prefix).HasMaxLength(200);
    }
}
