using Baya.Domain.Entities.Messaging;
using Baya.Domain.Entities.User;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace Baya.Infrastructure.Persistence.Configuration.MessagingConfig;

/// <summary>
/// <c>ticket_messages</c> — individual messages. <c>is_internal</c> (default 0) is the hard visibility boundary
/// (admin-only note); the <c>(ticket_id, sent_at)</c> index serves the ordered thread read.
/// </summary>
internal sealed class TicketMessageConfig : IEntityTypeConfiguration<TicketMessage>
{
    public void Configure(EntityTypeBuilder<TicketMessage> builder)
    {
        builder.ToTable("TicketMessages", "messaging");

        // Body is encrypted at rest (converter wired in ApplicationDbContext, refinement-phase-9 §9.5), so the
        // stored column holds base64 ciphertext (longer than the plaintext) — nvarchar(max), no length cap here.
        // The 4000-char plaintext limit is enforced at the boundary (Open/PostMessage validators).
        builder.Property(m => m.Body).IsRequired();
        builder.Property(m => m.IsInternal).HasDefaultValue(false);
        builder.Property(m => m.ClientMessageId).HasMaxLength(100);

        builder.HasIndex(m => new { m.TicketId, m.SentAt });

        // Optimistic-send idempotency backstop: at most one message per (ticket, client_message_id).
        builder.HasIndex(m => new { m.TicketId, m.ClientMessageId })
            .IsUnique()
            .HasFilter("[ClientMessageId] IS NOT NULL AND [DeletedAt] IS NULL")
            .HasDatabaseName("UX_TicketMessages_Ticket_ClientMessageId");

        builder.HasOne<User>().WithMany().HasForeignKey(m => m.SenderId).IsRequired();

        builder.HasQueryFilter(m => m.DeletedAt == null);
    }
}
