using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using MissionService.Domain.AggregatesModel.RewardAggregate;

namespace MissionService.Infrastructure.EntityConfigurations;

/// <summary>
/// EN: EF Core configuration for UserReward aggregate root
/// VI: Cấu hình EF Core cho UserReward aggregate root
/// </summary>
public class UserRewardEntityTypeConfiguration : IEntityTypeConfiguration<UserReward>
{
    public void Configure(EntityTypeBuilder<UserReward> builder)
    {
        builder.ToTable("user_rewards");

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

        builder.Property(r => r.UserId)
            .HasColumnName("user_id")
            .IsRequired();
        
        builder.HasIndex(r => r.UserId);

        builder.Property(r => r.SourceId)
            .HasColumnName("source_id")
            .IsRequired();
        
        // EN: Unique index - prevent duplicate rewards for same source
        // VI: Index duy nhất - ngăn thưởng trùng lặp cho cùng nguồn
        builder.HasIndex(r => r.SourceId)
            .IsUnique();

        builder.Property(r => r.Type)
            .HasColumnName("type")
            .HasConversion<int>();

        builder.Property(r => r.Status)
            .HasColumnName("status")
            .HasConversion<int>();

        // EN: Map RewardAmount value object / VI: Map value object RewardAmount
        builder.OwnsOne(r => r.Amount, amount =>
        {
            amount.Property(a => a.Points)
                .HasColumnName("points")
                .HasPrecision(18, 2);
                
            amount.Property(a => a.BonusPoints)
                .HasColumnName("bonus_points")
                .HasPrecision(18, 2);
                
            amount.Property(a => a.Currency)
                .HasColumnName("currency")
                .HasMaxLength(10)
                .HasDefaultValue("MP");
        });

        builder.Property(r => r.EarnedAt)
            .HasColumnName("earned_at");

        builder.Property(r => r.ClaimedAt)
            .HasColumnName("claimed_at");

        builder.Property(r => r.ExpiresAt)
            .HasColumnName("expires_at");
        
        // EN: Index for finding pending/expired rewards
        // VI: Index để tìm phần thưởng đang chờ/hết hạn
        builder.HasIndex(r => new { r.Status, r.ExpiresAt });
    }
}
