using Application.Abstractions.Data;
using Application.Abstractions.Messaging;
using Microsoft.EntityFrameworkCore;
namespace Application.Features.Api.Member.Items.Equipped;
///
/// 여러 회원의 장착 지위 아이템을 한 번에 조회한다 (댓글/채팅/프로필 목록 렌더용).
/// 만료(ExpiresAt 경과)·회수 아이템은 제외한다.
///
internal sealed class Handler(IAppDbContext db) : IQueryHandler
{
private const int MaxIDs = 200;
public async Task Handle(Query request, CancellationToken ct)
{
var ids = request.MemberIDs.Where(id => id > 0).Distinct().Take(MaxIDs).ToList();
if (ids.Count == 0)
{
return new Response([]);
}
var now = DateTime.UtcNow;
var rows = await db.MemberItem.AsNoTracking()
.Include(i => i.Product)
.Where(i => ids.Contains(i.MemberID)
&& i.IsEquipped
&& i.EquipSlot != null
&& i.RevokedAt == null
&& (i.ExpiresAt == null || i.ExpiresAt > now))
.Select(i => new
{
i.MemberID,
Slot = i.EquipSlot!.Value,
i.Kind,
ProductName = i.Product!.Name,
i.Product.EffectPayload,
i.Product.Thumbnail
})
.ToListAsync(ct);
var members = rows
.GroupBy(r => r.MemberID)
.Select(g => new Response.MemberEquip(
g.Key,
g.OrderBy(x => x.Slot)
.Select(x => new Response.EquippedItem(x.Slot, x.Kind, x.ProductName, x.EffectPayload, x.Thumbnail))
.ToList()))
.ToList();
return new Response(members);
}
}