using CMSMicroservice.Application.BlogPostCQ.Queries.GetBlogPost;
using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Application.Common.Models;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace CMSMicroservice.Application.BlogPostCQ.Queries.GetAllBlogPosts;

public class GetAllBlogPostsQueryHandler : IRequestHandler<GetAllBlogPostsQuery, GetAllBlogPostsResponseDto>
{
    private readonly IApplicationDbContext _context;

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

    public async Task<GetAllBlogPostsResponseDto> Handle(GetAllBlogPostsQuery request, CancellationToken cancellationToken)
    {
        var query = _context.BlogPosts
            .Include(x => x.BlogPostCategories).ThenInclude(x => x.BlogCategory)
            .Where(x => !x.IsDeleted);

        // فیلترها
        if (request.Status.HasValue)
            query = query.Where(x => x.Status == request.Status.Value);
        if (request.CategoryId.HasValue)
            query = query.Where(x => x.BlogPostCategories.Any(c => c.BlogCategoryId == request.CategoryId.Value));
        if (request.IsFeatured.HasValue)
            query = query.Where(x => x.IsFeatured == request.IsFeatured.Value);
        if (!string.IsNullOrEmpty(request.SearchTerm))
        {
            var term = request.SearchTerm.ToLower();
            query = query.Where(x => x.Title.ToLower().Contains(term) || (x.Summary != null && x.Summary.ToLower().Contains(term)));
        }

        var totalCount = await query.CountAsync(cancellationToken);

        // مرتب‌سازی
        query = request.SortBy?.ToLower() switch
        {
            "title" => query.OrderBy(x => x.Title),
            "viewcount" => query.OrderByDescending(x => x.ViewCount),
            "publishedat" => query.OrderByDescending(x => x.PublishedAt),
            _ => query.OrderByDescending(x => x.Created)
        };

        var posts = await query
            .Skip((request.PageNumber - 1) * request.PageSize)
            .Take(request.PageSize)
            .Select(x => new BlogPostListItemDto
            {
                Id = x.Id,
                Title = x.Title,
                Slug = x.Slug,
                Summary = x.Summary,
                FeaturedImageThumbnailPath = x.FeaturedImageThumbnailPath,
                Status = (int)x.Status,
                StatusName = GetBlogPostQueryHandler.GetStatusName(x.Status),
                PublishedAt = x.PublishedAt,
                ViewCount = x.ViewCount,
                IsFeatured = x.IsFeatured,
                Created = x.Created,
                Categories = x.BlogPostCategories.Select(c => new BlogPostCategoryDto
                {
                    Id = c.BlogCategory.Id,
                    Title = c.BlogCategory.Title,
                    Slug = c.BlogCategory.Slug
                }).ToList()
            })
            .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 GetAllBlogPostsResponseDto { MetaData = metaData, Models = posts };
    }
}
