using Application.Abstractions.Data; using Application.Abstractions.Messaging; using Microsoft.EntityFrameworkCore; namespace Application.Features.Api.Feed.GetReplies; public sealed class Handler(IAppDbContext db) : IQueryHandler { public async Task Handle(Query request, CancellationToken ct) { var postExists = await db.FeedPost.AsNoTracking().AnyAsync(p => p.ID == request.PostID && !p.IsDeleted, ct); if (!postExists) { return new Response { Total = 0, List = [] }; } var query = db.FeedComment.AsNoTracking().Where(c => c.FeedPostID == request.PostID); var total = await query.LongCountAsync(ct); var skip = (request.Page - 1) * request.PerPage; var rows = await query .OrderBy(c => c.CreatedAt) .Skip(skip) .Take(request.PerPage) .Select(c => new { c.ID, c.ParentID, ParentAuthorSID = c.Parent != null ? c.Parent.Member.SID : null, ParentAuthorName = c.Parent != null ? c.Parent.Member.Name : null, c.Content, c.IsDeleted, c.MemberID, AuthorSID = c.Member.SID, AuthorName = c.Member.Name, AuthorThumb = c.Member.Thumb, IsCreator = c.Member.IsCreator, c.Likes, c.CreatedAt }) .ToListAsync(ct); var viewerID = request.ViewerMemberID; var commentIDs = rows.Select(r => r.ID).ToList(); var likedSet = new HashSet(); if (viewerID is int vid && vid > 0 && commentIDs.Count > 0) { likedSet = [..await db.FeedCommentLike.AsNoTracking() .Where(r => r.MemberID == vid && commentIDs.Contains(r.FeedCommentID)) .Select(r => r.FeedCommentID) .ToListAsync(ct)]; } return new Response { Total = total, List = [..rows.Select(r => new Response.Row { ID = r.ID, ParentID = r.ParentID, ParentAuthorSID = r.ParentAuthorSID, ParentAuthorName = r.ParentAuthorName, Content = r.IsDeleted ? string.Empty : r.Content, IsDeleted = r.IsDeleted, AuthorSID = r.AuthorSID, AuthorName = r.AuthorName, AuthorThumb = r.AuthorThumb, IsCreator = r.IsCreator, Likes = r.Likes, HasLike = likedSet.Contains(r.ID), IsOwner = viewerID is int v && v > 0 && r.MemberID == v, CreatedAt = r.CreatedAt })] }; } }