using System.Text.Json;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using MktXService.Domain.AggregatesModel.AIConversationSessionAggregate;

namespace MktXService.Infrastructure.EntityConfigurations;

/// <summary>
/// EN: EF Core configuration for AIConversationSession entity with JSONB for context/slots.
/// VI: Cấu hình EF Core cho entity AIConversationSession với JSONB cho context/slots.
/// </summary>
public class AIConversationSessionEntityTypeConfiguration : IEntityTypeConfiguration<AIConversationSession>
{
    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
        WriteIndented = false
    };

    public void Configure(EntityTypeBuilder<AIConversationSession> builder)
    {
        builder.ToTable("ai_conversation_sessions");

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

        builder.Ignore(s => s.DomainEvents);

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

        builder.Property<Guid>("_conversationId")
            .HasColumnName("conversation_id")
            .IsRequired();

        builder.Property<string?>("_currentIntent")
            .HasColumnName("current_intent")
            .HasMaxLength(100);

        builder.Property<bool>("_isActive")
            .HasColumnName("is_active")
            .IsRequired();

        builder.Property<DateTime?>("_lastActivityAt")
            .HasColumnName("last_activity_at");

        builder.Property<DateTime>("_createdAt")
            .HasColumnName("created_at")
            .IsRequired();

        // ===========================================
        // EN: JSONB for conversation context (chat history)
        // VI: JSONB cho ngữ cảnh hội thoại (lịch sử chat)
        // ===========================================
        builder.Property<List<ContextItem>>("_context")
            .HasColumnName("context")
            .HasColumnType("jsonb")
            .HasConversion(
                v => JsonSerializer.Serialize(v, JsonOptions),
                v => JsonSerializer.Deserialize<List<ContextItem>>(v, JsonOptions) 
                     ?? new List<ContextItem>(),
                new ValueComparer<List<ContextItem>>(
                    (c1, c2) => c1!.SequenceEqual(c2!),
                    c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())),
                    c => c.ToList()));

        // EN: JSONB for slots (extracted entities from conversation)
        // VI: JSONB cho slots (entities được trích xuất từ hội thoại)
        builder.Property<Dictionary<string, object>>("_slots")
            .HasColumnName("slots")
            .HasColumnType("jsonb")
            .HasConversion(
                v => JsonSerializer.Serialize(v, JsonOptions),
                v => JsonSerializer.Deserialize<Dictionary<string, object>>(v, JsonOptions) 
                     ?? new Dictionary<string, object>(),
                new ValueComparer<Dictionary<string, object>>(
                    (c1, c2) => c1!.SequenceEqual(c2!),
                    c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())),
                    c => new Dictionary<string, object>(c)));

        // ===========================================
        // EN: Indexes
        // VI: Các index
        // ===========================================
        builder.HasIndex("_conversationId")
            .HasDatabaseName("ix_ai_sessions_conversation_id");

        builder.HasIndex("_isActive")
            .HasDatabaseName("ix_ai_sessions_is_active");

        // EN: Composite index for finding active session by conversation
        // VI: Index kết hợp để tìm session active theo conversation
        builder.HasIndex("_conversationId", "_isActive")
            .HasDatabaseName("ix_ai_sessions_conversation_active");
    }
}
