using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using PromotionService.Domain.AggregatesModel.CampaignAggregate;

namespace PromotionService.Infrastructure.EntityConfigurations;

/// <summary>
/// EN: EF Core configuration for Campaign entity.
/// VI: Cấu hình EF Core cho entity Campaign.
/// </summary>
public class CampaignEntityTypeConfiguration : IEntityTypeConfiguration<Campaign>
{
    public void Configure(EntityTypeBuilder<Campaign> builder)
    {
        builder.ToTable("campaigns");

        builder.HasKey(c => c.Id);

        builder.Property(c => c.Id)
            .HasColumnName("id")
            .ValueGeneratedNever();

        builder.Property(c => c.MerchantId)
            .HasColumnName("merchant_id")
            .IsRequired();

        builder.Property(c => c.Name)
            .HasColumnName("name")
            .HasMaxLength(255)
            .IsRequired();

        builder.Property(c => c.Description)
            .HasColumnName("description")
            .HasMaxLength(1000);

        // Backing Asset
        builder.Property(c => c.BackingAssetTypeId)
            .HasColumnName("backing_asset_type_id")
            .IsRequired();

        builder.Ignore(c => c.BackingAssetType);

        builder.Property(c => c.BackingAssetCode)
            .HasColumnName("backing_asset_code")
            .HasMaxLength(10)
            .IsRequired();

        builder.Property(c => c.FaceValue)
            .HasColumnName("face_value")
            .HasPrecision(18, 2)
            .IsRequired();

        // Acquisition
        builder.Property(c => c.AcquisitionTypeId)
            .HasColumnName("acquisition_type_id")
            .IsRequired();

        builder.Ignore(c => c.AcquisitionType);

        builder.Property(c => c.AcquisitionPrice)
            .HasColumnName("acquisition_price")
            .HasPrecision(18, 2);

        // Escrow
        builder.Property(c => c.EscrowHoldId)
            .HasColumnName("escrow_hold_id");

        builder.Property(c => c.EscrowWalletId)
            .HasColumnName("escrow_wallet_id");

        builder.Property(c => c.EscrowAmount)
            .HasColumnName("escrow_amount")
            .HasPrecision(18, 2);

        // Limits
        builder.Property(c => c.TotalVouchers)
            .HasColumnName("total_vouchers")
            .IsRequired();

        builder.Property(c => c.IssuedVouchers)
            .HasColumnName("issued_vouchers")
            .IsRequired();

        builder.Property(c => c.MaxPerUser)
            .HasColumnName("max_per_user");

        builder.Property(c => c.StartDate)
            .HasColumnName("start_date")
            .IsRequired();

        builder.Property(c => c.EndDate)
            .HasColumnName("end_date")
            .IsRequired();

        builder.Property(c => c.VoucherValidityDays)
            .HasColumnName("voucher_validity_days");

        // Status
        builder.Property(c => c.StatusId)
            .HasColumnName("status_id")
            .IsRequired();

        builder.Ignore(c => c.Status);

        builder.Property(c => c.CreatedAt)
            .HasColumnName("created_at")
            .IsRequired();

        builder.Property(c => c.UpdatedAt)
            .HasColumnName("updated_at")
            .IsRequired();

        // Navigation to Vouchers
        builder.HasMany(c => c.Vouchers)
            .WithOne()
            .HasForeignKey(v => v.CampaignId)
            .OnDelete(DeleteBehavior.Cascade);

        // Indexes
        builder.HasIndex(c => c.MerchantId)
            .HasDatabaseName("ix_campaigns_merchant_id");

        builder.HasIndex(c => c.StatusId)
            .HasDatabaseName("ix_campaigns_status_id");

        builder.HasIndex(c => new { c.StartDate, c.EndDate })
            .HasDatabaseName("ix_campaigns_date_range");
    }
}
