using ColaFlow.Modules.Mcp.Domain.Entities;
using ColaFlow.Modules.Mcp.Domain.ValueObjects;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System.Text.Json;

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

/// <summary>
/// EF Core configuration for PendingChange entity
/// </summary>
public class PendingChangeConfiguration : IEntityTypeConfiguration<PendingChange>
{
    public void Configure(EntityTypeBuilder<PendingChange> builder)
    {
        builder.ToTable("pending_changes");

        builder.HasKey(p => p.Id);

        builder.Property(p => p.Id)
            .HasColumnName("id")
            .IsRequired();

        builder.Property(p => p.TenantId)
            .HasColumnName("tenant_id")
            .IsRequired();

        builder.Property(p => p.ApiKeyId)
            .HasColumnName("api_key_id")
            .IsRequired();

        builder.Property(p => p.ToolName)
            .HasColumnName("tool_name")
            .HasMaxLength(200)
            .IsRequired();

        // Store DiffPreview as JSONB column using value converter
        builder.Property(p => p.Diff)
            .HasColumnName("diff")
            .HasColumnType("jsonb")
            .HasConversion(
                v => JsonSerializer.Serialize(v, (JsonSerializerOptions?)null),
                v => JsonSerializer.Deserialize<DiffPreview>(v, (JsonSerializerOptions?)null)!
            )
            .IsRequired();

        builder.Property(p => p.Status)
            .HasColumnName("status")
            .HasConversion<string>()
            .HasMaxLength(50)
            .IsRequired();

        builder.Property(p => p.CreatedAt)
            .HasColumnName("created_at")
            .IsRequired();

        builder.Property(p => p.ExpiresAt)
            .HasColumnName("expires_at")
            .IsRequired();

        builder.Property(p => p.ApprovedBy)
            .HasColumnName("approved_by");

        builder.Property(p => p.ApprovedAt)
            .HasColumnName("approved_at");

        builder.Property(p => p.RejectedBy)
            .HasColumnName("rejected_by");

        builder.Property(p => p.RejectedAt)
            .HasColumnName("rejected_at");

        builder.Property(p => p.RejectionReason)
            .HasColumnName("rejection_reason")
            .HasMaxLength(1000);

        builder.Property(p => p.AppliedAt)
            .HasColumnName("applied_at");

        builder.Property(p => p.ApplicationResult)
            .HasColumnName("application_result")
            .HasMaxLength(2000);

        // Indexes
        builder.HasIndex(p => p.TenantId)
            .HasDatabaseName("ix_pending_changes_tenant_id");

        builder.HasIndex(p => p.ApiKeyId)
            .HasDatabaseName("ix_pending_changes_api_key_id");

        builder.HasIndex(p => p.Status)
            .HasDatabaseName("ix_pending_changes_status");

        builder.HasIndex(p => p.CreatedAt)
            .HasDatabaseName("ix_pending_changes_created_at");

        builder.HasIndex(p => p.ExpiresAt)
            .HasDatabaseName("ix_pending_changes_expires_at");

        // Composite index for querying by tenant and status
        builder.HasIndex(p => new { p.TenantId, p.Status })
            .HasDatabaseName("ix_pending_changes_tenant_status");

        // Ignore domain events (handled by base class)
        builder.Ignore(p => p.DomainEvents);
    }
}
