using Baya.Application.Common;
using Baya.Application.Contracts.Common;
using Baya.Application.Contracts.Persistence;
using Baya.Application.Models.Catalog;
using Baya.Application.Models.Common;
using Mediator;

namespace Baya.Application.Features.Catalog.Queries.GetCatalogCategories;

internal sealed class GetCatalogCategoriesQueryHandler(IUnitOfWork unitOfWork, ICacheService cache)
    : IRequestHandler<GetCatalogCategoriesQuery, OperationResult<PagedResult<ServiceCategoryDto>>>
{
    public async ValueTask<OperationResult<PagedResult<ServiceCategoryDto>>> Handle(GetCatalogCategoriesQuery request, CancellationToken cancellationToken)
    {
        var (page, pageSize) = Pagination.Normalize(request.Page, request.PageSize);

        var version = await CatalogCache.VersionAsync(cache, cancellationToken);

        // The active-category set is small, near-static reference data — cache the whole ordered list once
        // per generation token and page it in memory, so a mutation's cache bump refreshes every page.
        var all = await cache.GetOrCreateAsync(
            CatalogCache.CategoriesKey(version),
            async ct => await unitOfWork.CatalogRepository.ListActiveCategoriesAsync(ct),
            CatalogCache.Ttl,
            cancellationToken);

        var items = all.Skip((page - 1) * pageSize).Take(pageSize).ToList();

        return OperationResult<PagedResult<ServiceCategoryDto>>.SuccessResult(
            new PagedResult<ServiceCategoryDto>(items, all.Count, page, pageSize));
    }
}
