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 McpApiKey entity
/// </summary>
public class McpApiKeyConfiguration : IEntityTypeConfiguration<McpApiKey>
{
    public void Configure(EntityTypeBuilder<McpApiKey> builder)
    {
        builder.ToTable("mcp_api_keys", "mcp");

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

        // Tenant and User IDs
        builder.Property(k => k.TenantId)
            .HasColumnName("tenant_id")
            .IsRequired();

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

        // Security fields
        builder.Property(k => k.KeyHash)
            .HasColumnName("key_hash")
            .HasMaxLength(64)
            .IsRequired();

        builder.Property(k => k.KeyPrefix)
            .HasColumnName("key_prefix")
            .HasMaxLength(16)
            .IsRequired();

        // Metadata
        builder.Property(k => k.Name)
            .HasColumnName("name")
            .HasMaxLength(255)
            .IsRequired();

        builder.Property(k => k.Description)
            .HasColumnName("description")
            .HasColumnType("text")
            .IsRequired(false);

        // Permissions - stored as JSONB
        builder.Property(k => k.Permissions)
            .HasColumnName("permissions")
            .HasColumnType("jsonb")
            .HasConversion(
                v => JsonSerializer.Serialize(v, (JsonSerializerOptions?)null),
                v => JsonSerializer.Deserialize<ApiKeyPermissions>(v, (JsonSerializerOptions?)null)!)
            .IsRequired();

        // IP Whitelist - stored as JSONB
        builder.Property(k => k.IpWhitelist)
            .HasColumnName("ip_whitelist")
            .HasColumnType("jsonb")
            .HasConversion(
                v => v != null ? JsonSerializer.Serialize(v, (JsonSerializerOptions?)null) : null,
                v => v != null ? JsonSerializer.Deserialize<List<string>>(v, (JsonSerializerOptions?)null) : null)
            .IsRequired(false);

        // Status
        builder.Property(k => k.Status)
            .HasColumnName("status")
            .HasConversion<int>()
            .IsRequired();

        builder.Property(k => k.LastUsedAt)
            .HasColumnName("last_used_at")
            .IsRequired(false);

        builder.Property(k => k.UsageCount)
            .HasColumnName("usage_count")
            .IsRequired();

        // Lifecycle
        builder.Property(k => k.CreatedAt)
            .HasColumnName("created_at")
            .IsRequired();

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

        builder.Property(k => k.RevokedAt)
            .HasColumnName("revoked_at")
            .IsRequired(false);

        builder.Property(k => k.RevokedBy)
            .HasColumnName("revoked_by")
            .IsRequired(false);

        // Indexes for performance
        builder.HasIndex(k => k.KeyPrefix)
            .HasDatabaseName("ix_mcp_api_keys_key_prefix")
            .IsUnique();

        builder.HasIndex(k => k.TenantId)
            .HasDatabaseName("ix_mcp_api_keys_tenant_id");

        builder.HasIndex(k => new { k.TenantId, k.UserId })
            .HasDatabaseName("ix_mcp_api_keys_tenant_user");

        builder.HasIndex(k => k.ExpiresAt)
            .HasDatabaseName("ix_mcp_api_keys_expires_at");

        builder.HasIndex(k => k.Status)
            .HasDatabaseName("ix_mcp_api_keys_status");

        // Ignore domain events (not persisted)
        builder.Ignore(k => k.DomainEvents);
    }
}
