using Application.Abstractions.Data;
using Application.Abstractions.Cache;
using Application.Abstractions.Messaging;
using Microsoft.EntityFrameworkCore;

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

public sealed class Handler(IAppDbContext db, ICacheService cache) : IQueryHandler<Query, Response>
{
    public async Task<Response> Handle(Query request, CancellationToken ct)
    {
        var cacheKey = CacheKeys.BoardMeta(request.BoardID);
        var cached = await cache.GetAsync<Response>(cacheKey, ct);
        if (cached is not null)
        {
            return cached;
        }

        var board = await db.Board
            .AsNoTracking()
            .FirstOrDefaultAsync(x => x.ID == request.BoardID, ct)
            ?? throw new KeyNotFoundException("게시판을 찾을 수 없습니다.");

        var meta = await db.BoardMeta
            .FirstOrDefaultAsync(x => x.BoardID == request.BoardID, ct);

        if (meta is null)
        {
            meta = new Domain.Entities.Forum.Boards.BoardMeta { BoardID = request.BoardID };
            db.BoardMeta.Add(meta);
            await db.SaveChangesAsync(ct);
        }

        var response = new Response(
            meta.ID,
            meta.BoardID,
            board.Code,
            board.Name,
            meta.List,
            meta.View,
            meta.Write,
            meta.Comment,
            meta.General,
            meta.Permission,
            meta.Notify,
            meta.NotifyTemplate,
            meta.Exp);

        await cache.SetAsync(cacheKey, response, ct);
        return response;
    }
}