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 Story entity
/// </summary>
public class StoryConfiguration : IEntityTypeConfiguration<Story>
{
    public void Configure(EntityTypeBuilder<Story> builder)
    {
        builder.ToTable("Stories");

        // Primary key
        builder.HasKey("Id");

        // Id conversion
        builder.Property(s => s.Id)
            .HasConversion(
                id => id.Value,
                value => StoryId.From(value))
            .IsRequired()
            .ValueGeneratedNever();

        // TenantId (required for multi-tenancy)
        builder.Property(s => s.TenantId)
            .HasConversion(
                id => id.Value,
                value => TenantId.From(value))
            .IsRequired()
            .HasColumnName("tenant_id");

        // EpicId (foreign key)
        builder.Property(s => s.EpicId)
            .HasConversion(
                id => id.Value,
                value => EpicId.From(value))
            .IsRequired();

        // Basic properties
        builder.Property(s => s.Title)
            .HasMaxLength(200)
            .IsRequired();

        builder.Property(s => s.Description)
            .HasMaxLength(4000);

        // Status enumeration
        builder.Property(s => s.Status)
            .HasConversion(
                st => st.Name,
                name => Enumeration.FromDisplayName<WorkItemStatus>(name))
            .HasMaxLength(50)
            .IsRequired();

        // Priority enumeration
        builder.Property(s => s.Priority)
            .HasConversion(
                p => p.Name,
                name => Enumeration.FromDisplayName<TaskPriority>(name))
            .HasMaxLength(50)
            .IsRequired();

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

        // AssigneeId (optional)
        builder.Property(s => s.AssigneeId)
            .HasConversion(
                id => id != null ? id.Value : (Guid?)null,
                value => value.HasValue ? UserId.From(value.Value) : null);

        // Effort tracking
        builder.Property(s => s.EstimatedHours);
        builder.Property(s => s.ActualHours);

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

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

        // Configure Tasks collection (owned by Story in the aggregate)
        // Use string-based FK name because StoryId is a value object with conversion configured in WorkTaskConfiguration
        builder.HasMany<WorkTask>("Tasks")
            .WithOne()
            .HasForeignKey("StoryId")
            .OnDelete(DeleteBehavior.Cascade);

        // Indexes
        builder.HasIndex(s => s.TenantId)
            .HasDatabaseName("ix_stories_tenant_id");
        builder.HasIndex(s => s.EpicId);
        builder.HasIndex(s => s.AssigneeId);
        builder.HasIndex(s => s.CreatedAt);
    }
}
