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

namespace Baya.Infrastructure.Persistence.Configuration.MessagingConfig;

/// <summary>
/// <c>tickets</c> — the root of all post-booking communication. <c>UNIQUE(reference_code)</c> backs the stable
/// human-facing support id; the <c>status</c> and <c>(status, created_at)</c> indexes serve the admin queue;
/// the <c>booking_id</c>/<c>refund_id</c> indexes serve the "tickets for this booking/refund" lookups. Both
/// links are optional (nullable FK) — a pure support ticket has neither.
/// </summary>
internal sealed class TicketConfig : IEntityTypeConfiguration<Ticket>
{
    public void Configure(EntityTypeBuilder<Ticket> builder)
    {
        builder.ToTable("Tickets", "messaging");

        builder.Property(t => t.ReferenceCode).HasMaxLength(40).IsRequired();
        builder.Property(t => t.Subject).HasMaxLength(300);
        builder.Property(t => t.Status).HasMaxLength(20).IsRequired();
        builder.Property(t => t.Category).HasMaxLength(30).IsRequired();

        builder.HasIndex(t => t.ReferenceCode).IsUnique();
        builder.HasIndex(t => t.Status);
        builder.HasIndex(t => t.BookingId);
        builder.HasIndex(t => t.RefundId);
        builder.HasIndex(t => new { t.Status, t.CreatedAt });

        builder.HasOne<User>().WithMany().HasForeignKey(t => t.OpenedById).IsRequired();
        builder.HasOne<User>().WithMany().HasForeignKey(t => t.ClosedById).IsRequired(false);
        builder.HasOne<Booking>().WithMany().HasForeignKey(t => t.BookingId).IsRequired(false);
        builder.HasOne<Refund>().WithMany().HasForeignKey(t => t.RefundId).IsRequired(false);

        builder.HasMany(t => t.Participants).WithOne(p => p.Ticket).HasForeignKey(p => p.TicketId).IsRequired();
        builder.HasMany(t => t.Messages).WithOne(m => m.Ticket).HasForeignKey(m => m.TicketId).IsRequired();

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