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

namespace MissionService.Infrastructure.EntityConfigurations;

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

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

        builder.Property(m => m.Code)
            .HasColumnName("code")
            .HasMaxLength(100)
            .IsRequired();
        
        builder.HasIndex(m => m.Code)
            .IsUnique();

        builder.Property(m => m.TitleEn)
            .HasColumnName("title_en")
            .HasMaxLength(200)
            .IsRequired();

        builder.Property(m => m.TitleVi)
            .HasColumnName("title_vi")
            .HasMaxLength(200)
            .IsRequired();

        builder.Property(m => m.DescriptionEn)
            .HasColumnName("description_en")
            .HasMaxLength(2000);

        builder.Property(m => m.DescriptionVi)
            .HasColumnName("description_vi")
            .HasMaxLength(2000);

        // EN: Map Enumeration types / VI: Map các Enumeration types
        builder.Property(m => m.Type)
            .HasColumnName("type_id")
            .HasConversion(
                t => t.Id,
                id => MissionType.FromValue<MissionType>(id));

        builder.Property(m => m.Category)
            .HasColumnName("category_id")
            .HasConversion(
                c => c.Id,
                id => MissionCategory.FromValue<MissionCategory>(id));

        builder.Property(m => m.Status)
            .HasColumnName("status_id")
            .HasConversion(
                s => s.Id,
                id => MissionStatus.FromValue<MissionStatus>(id));

        builder.Property(m => m.Frequency)
            .HasColumnName("frequency_id")
            .HasConversion(
                f => f.Id,
                id => FrequencyType.FromValue<FrequencyType>(id));

        // EN: Map Reward value object / VI: Map value object Reward
        builder.OwnsOne(m => m.Reward, reward =>
        {
            reward.Property(r => r.Points)
                .HasColumnName("reward_points")
                .HasPrecision(18, 2);
                
            reward.Property(r => r.MiningBoostPercent)
                .HasColumnName("reward_mining_boost")
                .HasPrecision(5, 2);
                
            reward.Property(r => r.ExperiencePoints)
                .HasColumnName("reward_xp");
                
            reward.Property(r => r.BadgeId)
                .HasColumnName("reward_badge_id")
                .HasMaxLength(50);
        });

        builder.Property(m => m.MaxCompletions)
            .HasColumnName("max_completions");

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

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

        builder.Property(m => m.Priority)
            .HasColumnName("priority");

        // EN: Navigation to rules / VI: Navigation đến rules
        builder.HasMany(m => m.Rules)
            .WithOne()
            .HasForeignKey("mission_id")
            .OnDelete(DeleteBehavior.Cascade);

        builder.Navigation(m => m.Rules)
            .UsePropertyAccessMode(PropertyAccessMode.Field);
    }
}

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

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

        builder.Property<Guid>("mission_id");

        builder.Property(r => r.RuleType)
            .HasColumnName("rule_type")
            .HasMaxLength(50)
            .IsRequired();

        builder.Property(r => r.Operator)
            .HasColumnName("operator")
            .HasMaxLength(20)
            .IsRequired();

        builder.Property(r => r.Value)
            .HasColumnName("value")
            .HasMaxLength(500)
            .IsRequired();

        builder.Property(r => r.Metadata)
            .HasColumnName("metadata")
            .HasColumnType("jsonb");
    }
}

#region Enumeration Tables

public class MissionTypeEntityTypeConfiguration : IEntityTypeConfiguration<MissionType>
{
    public void Configure(EntityTypeBuilder<MissionType> builder)
    {
        builder.ToTable("mission_types");
        builder.HasKey(t => t.Id);
        builder.Property(t => t.Id).HasColumnName("id").ValueGeneratedNever();
        builder.Property(t => t.Name).HasColumnName("name").HasMaxLength(50).IsRequired();
        
        // EN: Seed data / VI: Dữ liệu mẫu
        builder.HasData(
            MissionType.Video,
            MissionType.Click,
            MissionType.Upload,
            MissionType.Invite,
            MissionType.CheckIn,
            MissionType.Social
        );
    }
}

public class MissionCategoryEntityTypeConfiguration : IEntityTypeConfiguration<MissionCategory>
{
    public void Configure(EntityTypeBuilder<MissionCategory> builder)
    {
        builder.ToTable("mission_categories");
        builder.HasKey(c => c.Id);
        builder.Property(c => c.Id).HasColumnName("id").ValueGeneratedNever();
        builder.Property(c => c.Name).HasColumnName("name").HasMaxLength(50).IsRequired();
        
        builder.HasData(
            MissionCategory.Daily,
            MissionCategory.Weekly,
            MissionCategory.Special,
            MissionCategory.Onboarding,
            MissionCategory.Event
        );
    }
}

public class MissionStatusEntityTypeConfiguration : IEntityTypeConfiguration<MissionStatus>
{
    public void Configure(EntityTypeBuilder<MissionStatus> builder)
    {
        builder.ToTable("mission_statuses");
        builder.HasKey(s => s.Id);
        builder.Property(s => s.Id).HasColumnName("id").ValueGeneratedNever();
        builder.Property(s => s.Name).HasColumnName("name").HasMaxLength(50).IsRequired();
        
        builder.HasData(
            MissionStatus.Draft,
            MissionStatus.Active,
            MissionStatus.Paused,
            MissionStatus.Expired,
            MissionStatus.Archived
        );
    }
}

public class FrequencyTypeEntityTypeConfiguration : IEntityTypeConfiguration<FrequencyType>
{
    public void Configure(EntityTypeBuilder<FrequencyType> builder)
    {
        builder.ToTable("frequency_types");
        builder.HasKey(f => f.Id);
        builder.Property(f => f.Id).HasColumnName("id").ValueGeneratedNever();
        builder.Property(f => f.Name).HasColumnName("name").HasMaxLength(50).IsRequired();
        
        builder.HasData(
            FrequencyType.Once,
            FrequencyType.Daily,
            FrequencyType.Weekly,
            FrequencyType.Unlimited
        );
    }
}

#endregion
