using Application.Abstractions.Messaging;
using Application.Abstractions.Data;
using Application.Abstractions.Forum;
using Microsoft.EntityFrameworkCore;
using SharedKernel.Results;

namespace Application.Features.Api.Forum.Post.Delete;

public sealed class Handler(IAppDbContext db, IBoardPermissionService permissionService) : ICommandHandler<Command, Result>
{
    public async Task<Result> Handle(Command request, CancellationToken ct)
    {
        var post = await db.Post.FirstOrDefaultAsync(x => x.ID == request.ID, ct);
        if (post is null)
        {
            return Result.Failure(Error.NotFound("Post.NotFound", "게시글을 찾을 수 없습니다."));
        }

        if (post.MemberID != request.MemberID)
        {
            var reqMember = await db.Member.AsNoTracking().FirstOrDefaultAsync(x => x.ID == request.MemberID, ct);
            if (reqMember is null || !reqMember.IsAdmin)
            {
                var mgr = await permissionService.GetBoardManagerAsync(post.BoardID, request.MemberID, ct);
                if (mgr is null || !mgr.CanDelete)
                {
                    return Result.Failure(Error.Forbidden("Post.Forbidden", "삭제 권한이 없습니다."));
                }
            }
        }

        post.IsDeleted = true;
        post.DeletedAt = DateTime.UtcNow;

        // Board 게시글 카운트 감소
        var board = await db.Board.FirstOrDefaultAsync(x => x.ID == post.BoardID, ct);
        if (board is not null)
        {
            board.Posts--;
            board.UpdatedAt = DateTime.UtcNow;

            var boardGroup = await db.BoardGroup.FirstOrDefaultAsync(x => x.ID == board.BoardGroupID, ct);
            if (boardGroup is not null)
            {
                boardGroup.Posts--;
                boardGroup.UpdatedAt = DateTime.UtcNow;
            }
        }

        // MemberStats 게시글 수 감소
        if (post.MemberID.HasValue)
        {
            var memberStats = await db.MemberStats.FirstOrDefaultAsync(x => x.MemberID == post.MemberID.Value, ct);
            if (memberStats is not null)
            {
                memberStats.PostCount--;
            }
        }

        await db.SaveChangesAsync(ct);

        return Result.Success();
    }
}