using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using ColaFlow.Modules.ProjectManagement.Domain.Aggregates.ProjectAggregate;
using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
using ColaFlow.Shared.Kernel.Common;

namespace ColaFlow.Modules.ProjectManagement.Infrastructure.Persistence.Configurations;

/// <summary>
/// Entity configuration for Project aggregate root
/// </summary>
public class ProjectConfiguration : IEntityTypeConfiguration<Project>
{
    public void Configure(EntityTypeBuilder<Project> builder)
    {
        builder.ToTable("Projects");

        // Primary key
        builder.HasKey(p => p.Id);

        // Id conversion (StronglyTypedId to Guid)
        builder.Property(p => p.Id)
            .HasConversion(
                id => id.Value,
                value => ProjectId.From(value))
            .IsRequired()
            .ValueGeneratedNever();

        // TenantId conversion
        builder.Property(p => p.TenantId)
            .HasConversion(
                id => id.Value,
                value => TenantId.From(value))
            .IsRequired();

        // Basic properties
        builder.Property(p => p.Name)
            .HasMaxLength(200)
            .IsRequired();

        builder.Property(p => p.Description)
            .HasMaxLength(2000);

        // ProjectKey as owned value object
        builder.OwnsOne(p => p.Key, kb =>
        {
            kb.Property(k => k.Value)
                .HasColumnName("Key")
                .HasMaxLength(20)
                .IsRequired();

            kb.HasIndex(k => k.Value).IsUnique();
        });

        // Status enumeration (stored as string)
        builder.Property(p => p.Status)
            .HasConversion(
                s => s.Name,
                name => Enumeration.FromDisplayName<ProjectStatus>(name))
            .HasMaxLength(50)
            .IsRequired();

        // OwnerId conversion
        builder.Property(p => p.OwnerId)
            .HasConversion(
                id => id.Value,
                value => UserId.From(value))
            .IsRequired();

        // Timestamps
        builder.Property(p => p.CreatedAt)
            .IsRequired();

        builder.Property(p => p.UpdatedAt);

        // Relationships - Epics collection (owned by aggregate)
        // Configure the one-to-many relationship with Epic
        // Use string-based FK name because ProjectId is a value object with conversion configured in EpicConfiguration
        builder.HasMany<Epic>("Epics")
            .WithOne()
            .HasForeignKey("ProjectId")
            .OnDelete(DeleteBehavior.Cascade);

        // Indexes for performance
        builder.HasIndex(p => p.CreatedAt);
        builder.HasIndex(p => p.OwnerId);
        builder.HasIndex(p => p.TenantId);

        // Ignore DomainEvents (handled separately)
        builder.Ignore(p => p.DomainEvents);
    }
}
