using Application.Abstractions.Messaging;
using Application.Abstractions.Data;
using Domain.Entities.Forum.ValueObject;
using Microsoft.EntityFrameworkCore;

namespace Application.Features.Admin.Forum.Post.Get;

public sealed class Handler(IAppDbContext db) : IQueryHandler<Query, Response>
{
    public async Task<Response> Handle(Query request, CancellationToken ct)
    {
        var item = await db.Post.AsNoTracking().Include(c => c.Board).ThenInclude(c => c.BoardMeta).Include(c => c.BoardPrefix).Include(c => c.PostFile).Include(c => c.PostImage).Include(c => c.PostTag).ThenInclude(c => c.Tag).FirstOrDefaultAsync(x => x.ID == request.ID, ct);
        if (item is null)
        {
            throw new KeyNotFoundException("게시글을 찾을 수 없습니다.");
        }

        return new Response(
            item.ID,
            item.BoardID,
            item.Board.Name,
            item.BoardPrefixID,
            item.BoardPrefix?.Name,
            item.BoardPrefix?.Color,
            item.Subject,
            item.Content,
            item.Thumbnail,
            item.Name,
            item.SID,
            item.IsNotice,
            item.IsSecret,
            item.IsAnonymous,
            item.IsSpeaker,
            item.IsDeleted,
            item.Views,
            item.Likes,
            item.Dislikes,
            item.Comments,
            item.Images,
            item.Medias,
            item.Files,
            item.Tags,
            [..item.PostFile.OrderByDescending(f => f.ID).Select(f => new Response.FileItem(
                f.ID, f.FileName, f.Url, f.Extension, f.Size, f.Downloads, f.IsDisabled, f.CreatedAt
            ))],
            [..item.PostImage.OrderByDescending(f => f.ID).Select(f => new Response.ImageItem(
                f.ID, f.FileName, f.Url, f.Extension, f.Size, f.IsDisabled
            ))],
            [..item.PostTag.Select(t => new Response.TagItem(
                t.TagID, t.Tag.Name, t.Tag.Slug
            ))],
            item.Board.BoardMeta.List.Layout == BoardLayout.QnA,
            item.UpdatedAt,
            item.CreatedAt
        );
    }
}
