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

namespace MktXService.Infrastructure.EntityConfigurations;

/// <summary>
/// EN: EF Core configuration for Template entity.
/// VI: Cấu hình EF Core cho entity Template.
/// </summary>
public class TemplateEntityTypeConfiguration : IEntityTypeConfiguration<Template>
{
    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
        WriteIndented = false
    };

    public void Configure(EntityTypeBuilder<Template> builder)
    {
        builder.ToTable("templates");

        builder.HasKey(t => t.Id);
        builder.Ignore(t => t.DomainEvents);

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

        builder.Property<Guid>("_merchantId")
            .HasColumnName("merchant_id")
            .IsRequired();

        builder.Property<string>("_name")
            .HasColumnName("name")
            .HasMaxLength(200)
            .IsRequired();

        builder.Property<string>("_type")
            .HasColumnName("type")
            .HasMaxLength(50)
            .IsRequired();

        builder.Property<string>("_content")
            .HasColumnName("content")
            .IsRequired();

        // EN: Variables list as JSONB
        builder.Property<List<string>>("_variables")
            .HasColumnName("variables")
            .HasColumnType("jsonb")
            .HasConversion(
                v => JsonSerializer.Serialize(v, JsonOptions),
                v => JsonSerializer.Deserialize<List<string>>(v, JsonOptions) ?? new List<string>(),
                new ValueComparer<List<string>>(
                    (c1, c2) => c1!.SequenceEqual(c2!),
                    c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())),
                    c => c.ToList()));

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

        builder.Property<DateTime?>("_updatedAt")
            .HasColumnName("updated_at");

        // EN: Indexes
        builder.HasIndex("_merchantId")
            .HasDatabaseName("ix_templates_merchant_id");

        builder.HasIndex("_type")
            .HasDatabaseName("ix_templates_type");

        builder.HasIndex("_name")
            .HasDatabaseName("ix_templates_name");
    }
}
