using AdsServingService.Domain.AggregatesModel.AuctionAggregate;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace AdsServingService.Infrastructure.EntityConfigurations;

/// <summary>
/// EN: EF Core entity configuration for Auction aggregate.
/// VI: Cấu hình entity EF Core cho aggregate Auction.
/// </summary>
public class AuctionEntityTypeConfiguration : IEntityTypeConfiguration<Auction>
{
    public void Configure(EntityTypeBuilder<Auction> builder)
    {
        // Table mapping
        builder.ToTable("auctions");

        // Primary key
        builder.HasKey(a => a.Id);
        builder.Property(a => a.Id)
            .HasColumnName("id")
            .ValueGeneratedNever();

        // Properties
        builder.Property(a => a.UserId)
            .HasColumnName("user_id")
            .IsRequired();

        builder.Property(a => a.PlacementType)
            .HasColumnName("placement_type")
            .HasMaxLength(50)
            .IsRequired();

        builder.Property<DateTime>("_auctionTime")
            .HasColumnName("auction_time")
            .IsRequired();

        // Owned collection: Bids (stored as JSONB for performance)
        // EN: Store bids as JSONB for fast read/write in high-throughput scenarios
        // VI: Lưu bids dưới dạng JSONB để đọc/ghi nhanh trong các tình huống throughput cao
        // Note: EF Core 10 has issues with OwnsMany + ToJson, so we store as a simple property
        builder.Ignore(a => a.Bids);
        builder.Property<string>("_bidsJson")
            .HasColumnName("bids")
            .HasColumnType("jsonb");

        // Owned value object: AuctionResult (nullable)
        builder.OwnsOne<AuctionResult>("_result", resultBuilder =>
        {
            resultBuilder.Property(r => r.WinningAdId)
                .HasColumnName("winning_ad_id");
            
            resultBuilder.Property(r => r.WinningCampaignId)
                .HasColumnName("winning_campaign_id");
            
            resultBuilder.Property(r => r.FinalPrice)
                .HasColumnName("final_price")
                .HasColumnType("decimal(18,4)");
            
            resultBuilder.Property(r => r.WinningeCPM)
                .HasColumnName("winning_ecpm")
                .HasColumnType("decimal(18,4)");
        });

        // Indexes for query performance
        // EN: Index on user_id for user-specific queries
        // VI: Index trên user_id cho các truy vấn theo người dùng
        builder.HasIndex(a => a.UserId)
            .HasDatabaseName("ix_auctions_user_id");

        // EN: Index on placement_type for placement-specific queries
        // VI: Index trên placement_type cho các truy vấn theo vị trí
        builder.HasIndex(a => a.PlacementType)
            .HasDatabaseName("ix_auctions_placement_type");

        // EN: Index on auction_time for time-range queries
        // VI: Index trên auction_time cho các truy vấn theo khoảng thời gian
        builder.HasIndex("_auctionTime")
            .HasDatabaseName("ix_auctions_auction_time");

        // Composite index for common queries
        builder.HasIndex(a => new { a.PlacementType, a.UserId })
            .HasDatabaseName("ix_auctions_placement_user");
    }
}
