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

namespace Application.Features.Admin.Forum.BoardPrefix.Save;

internal sealed class Handler(IAppDbContext db) : ICommandHandler<Command>
{
    public async Task Handle(Command request, CancellationToken ct)
    {
        // 삭제
        if (request.DeleteIDs is { Length: > 0 })
        {
            var deleteTargets = await db.BoardPrefix
                .Where(c => c.BoardID == request.BoardID && request.DeleteIDs.Contains(c.ID))
                .ToListAsync(ct);

            // 게시글이 등록된 말머리는 삭제 불가
            var hasPostsTargets = deleteTargets.Where(c => c.Posts > 0).ToList();
            if (hasPostsTargets.Count > 0)
            {
                throw new InvalidOperationException("게시글이 등록된 말머리는 삭제할 수 없습니다.");
            }

            if (deleteTargets.Count > 0)
            {
                db.BoardPrefix.RemoveRange(deleteTargets);
            }
        }

        // 수정
        if (request.Updates is { Count: > 0 })
        {
            var updateIDs = request.Updates.Select(c => c.ID).ToList();
            var updateTargets = await db.BoardPrefix
                .Where(c => c.BoardID == request.BoardID && updateIDs.Contains(c.ID))
                .ToListAsync(ct);

            var updateByID = updateTargets.ToDictionary(c => c.ID);

            foreach (var row in request.Updates)
            {
                if (!updateByID.TryGetValue(row.ID, out var existing))
                {
                    throw new InvalidOperationException($"존재하지 않는 ID: {row.ID}");
                }

                existing.Name = row.Name;
                existing.Color = row.Color;
                existing.Order = row.Order;
                existing.IsActive = row.IsActive;
                existing.UpdatedAt = DateTime.UtcNow;
            }
        }

        // 신규 추가
        if (request.NewItem is not null)
        {
            var currentCount = await db.BoardPrefix
                .AsNoTracking()
                .CountAsync(c => c.BoardID == request.BoardID, ct);

            if (currentCount >= BoardConstant.MaxPrefixCount)
            {
                throw new InvalidOperationException($"말머리는 최대 {BoardConstant.MaxPrefixCount}개까지 등록할 수 있습니다.");
            }

            db.BoardPrefix.Add(new Domain.Entities.Forum.Boards.BoardPrefix
            {
                BoardID = request.BoardID,
                Name = request.NewItem.Name,
                Color = request.NewItem.Color,
                Order = request.NewItem.Order
            });
        }

        await db.SaveChangesAsync(ct);
    }
}