using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using MissionService.Domain.AggregatesModel.TaskAggregate;
using TaskStatus = MissionService.Domain.AggregatesModel.TaskAggregate.TaskStatus;

namespace MissionService.Infrastructure.EntityConfigurations;

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

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

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

        builder.Property(t => t.MissionId)
            .HasColumnName("mission_id")
            .IsRequired();
        
        builder.HasIndex(t => t.MissionId);
        
        // EN: Composite index for user + mission / VI: Index kết hợp cho user + mission
        builder.HasIndex(t => new { t.UserId, t.MissionId });

        // EN: Map TaskStatus Enumeration / VI: Map TaskStatus Enumeration
        builder.Property(t => t.Status)
            .HasColumnName("status_id")
            .HasConversion(
                s => s.Id,
                id => TaskStatus.FromValue<TaskStatus>(id));

        // EN: Map Progress value object / VI: Map value object Progress
        builder.OwnsOne(t => t.Progress, progress =>
        {
            progress.Property(p => p.CurrentValue)
                .HasColumnName("progress_current");
                
            progress.Property(p => p.TargetValue)
                .HasColumnName("progress_target");
                
            progress.Property(p => p.LastUpdated)
                .HasColumnName("progress_updated_at");
        });

        // EN: Map Evidence value object / VI: Map value object Evidence
        builder.OwnsOne(t => t.Evidence, evidence =>
        {
            evidence.Property(e => e.Type)
                .HasColumnName("evidence_type");
                
            evidence.Property(e => e.Data)
                .HasColumnName("evidence_data")
                .HasMaxLength(4000);
                
            evidence.Property(e => e.ScreenshotUrl)
                .HasColumnName("evidence_screenshot_url")
                .HasMaxLength(500);
                
            evidence.Property(e => e.VideoUrl)
                .HasColumnName("evidence_video_url")
                .HasMaxLength(500);
                
            evidence.Property(e => e.CapturedAt)
                .HasColumnName("evidence_captured_at");
        });

        // EN: Map Verification value object / VI: Map value object Verification
        builder.OwnsOne(t => t.Verification, verification =>
        {
            verification.Property(v => v.IsValid)
                .HasColumnName("verification_valid");
                
            verification.Property(v => v.FailureReason)
                .HasColumnName("verification_failure_reason")
                .HasMaxLength(500);
                
            verification.Property(v => v.Method)
                .HasColumnName("verification_method");
                
            verification.Property(v => v.VerifiedBy)
                .HasColumnName("verification_by");
                
            verification.Property(v => v.VerifiedAt)
                .HasColumnName("verification_at");
        });

        builder.Property(t => t.RewardClaimed)
            .HasColumnName("reward_claimed");

        builder.Property(t => t.StartedAt)
            .HasColumnName("started_at");

        builder.Property(t => t.CompletedAt)
            .HasColumnName("completed_at");

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

/// <summary>
/// EN: EF Core configuration for TaskStatus enumeration
/// VI: Cấu hình EF Core cho TaskStatus enumeration
/// </summary>
public class TaskStatusEntityTypeConfiguration : IEntityTypeConfiguration<TaskStatus>
{
    public void Configure(EntityTypeBuilder<TaskStatus> builder)
    {
        builder.ToTable("task_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(
            TaskStatus.Pending,
            TaskStatus.InProgress,
            TaskStatus.PendingVerification,
            TaskStatus.Completed,
            TaskStatus.Rejected,
            TaskStatus.Cancelled,
            TaskStatus.Expired
        );
    }
}
