using CMSMicroservice.Application.BlogCategoryCQ.Queries.GetBlogCategory;
using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Application.Common.Models;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace CMSMicroservice.Application.BlogCategoryCQ.Queries.GetAllBlogCategories;

public class GetAllBlogCategoriesQueryHandler : IRequestHandler<GetAllBlogCategoriesQuery, GetAllBlogCategoriesResponseDto>
{
    private readonly IApplicationDbContext _context;

    public GetAllBlogCategoriesQueryHandler(IApplicationDbContext context)
    {
        _context = context;
    }

    public async Task<GetAllBlogCategoriesResponseDto> Handle(GetAllBlogCategoriesQuery request, CancellationToken cancellationToken)
    {
        var query = _context.BlogCategories
            .Include(x => x.BlogPostCategories)
            .Where(x => !x.IsDeleted);

        if (!string.IsNullOrEmpty(request.SearchTerm))
        {
            var term = request.SearchTerm.ToLower();
            query = query.Where(x => x.Title.ToLower().Contains(term) || x.Slug.ToLower().Contains(term));
        }

        var totalCount = await query.CountAsync(cancellationToken);

        var categories = await query
            .OrderBy(x => x.SortOrder)
            .ThenBy(x => x.Title)
            .Skip((request.PageNumber - 1) * request.PageSize)
            .Take(request.PageSize)
            .Select(x => new BlogCategoryDto
            {
                Id = x.Id,
                Title = x.Title,
                Slug = x.Slug,
                Description = x.Description,
                IconName = x.IconName,
                SortOrder = x.SortOrder,
                IsActive = x.IsActive,
                PostCount = x.BlogPostCategories.Count,
                Created = x.Created,
                LastModified = x.LastModified
            })
            .ToListAsync(cancellationToken);

        var metaData = new MetaData
        {
            TotalCount = totalCount,
            PageSize = request.PageSize,
            CurrentPage = request.PageNumber,
            TotalPage = (int)Math.Ceiling(totalCount / (double)request.PageSize),
            HasNext = request.PageNumber < (int)Math.Ceiling(totalCount / (double)request.PageSize),
            HasPrevious = request.PageNumber > 1
        };

        return new GetAllBlogCategoriesResponseDto { MetaData = metaData, Models = categories };
    }
}
