using CMSMicroservice.Application.Common.Extensions;
using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Application.Common.Models;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace CMSMicroservice.Application.DiscountShopCQ.Queries.GetDiscountProducts;

public class GetDiscountProductsQueryHandler : IRequestHandler<GetDiscountProductsQuery, GetDiscountProductsResponseDto>
{
    private readonly IApplicationDbContext _context;

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

    public async Task<GetDiscountProductsResponseDto> Handle(GetDiscountProductsQuery request, CancellationToken cancellationToken)
    {
        var query = _context.DiscountProducts.AsQueryable();

        // Apply filters
        if (request.CategoryId.HasValue)
        {
            var productIds = await _context.DiscountProductCategories
                .Where(pc => pc.CategoryId == request.CategoryId.Value)
                .Select(pc => pc.ProductId)
                .ToListAsync(cancellationToken);

            query = query.Where(p => productIds.Contains(p.Id));
        }

        if (!string.IsNullOrWhiteSpace(request.SearchTerm))
        {
            query = query.Where(p => 
                p.Title.Contains(request.SearchTerm) || 
                p.ShortInfomation.Contains(request.SearchTerm));
        }

        if (request.IsActive.HasValue)
        {
            query = query.Where(p => p.IsActive == request.IsActive.Value);
        }

        if (request.InStock == true)
            query = query.Where(p => p.RemainingCount > 0);
        else if (request.InStock == false)
            query = query.Where(p => p.RemainingCount <= 0);

        if (request.MinPrice.HasValue)
        {
            query = query.Where(p => p.Price >= request.MinPrice.Value);
        }

        if (request.MaxPrice.HasValue)
        {
            query = query.Where(p => p.Price <= request.MaxPrice.Value);
        }

        // موجودی‌دارها اول، سپس سورت درخواستی
        query = query.ApplyOrderWithInStockPriority(request.SortBy, p => p.RemainingCount > 0);

        var totalCount = await query.CountAsync(cancellationToken);

        var pagination = request.PaginationQuery ?? new PaginationState { PageNumber = 1, PageSize = 10 };

        var products = await query
            .Skip((pagination.PageNumber - 1) * pagination.PageSize)
            .Take(pagination.PageSize)
            .Select(p => new DiscountProductDto
            {
                Id = p.Id,
                Title = p.Title,
                ShortInfomation = p.ShortInfomation,
                Price = p.Price,
                MaxDiscountPercent = p.MaxDiscountPercent,
                Rate = p.Rate,
                ImagePath = p.ImagePath,
                ThumbnailPath = p.ThumbnailPath,
                SaleCount = p.SaleCount,
                ViewCount = p.ViewCount,
                RemainingCount = p.RemainingCount,
                IsActive = p.IsActive
            })
            .ToListAsync(cancellationToken);

        return new GetDiscountProductsResponseDto
        {
            MetaData = new MetaData
            {
                TotalCount = totalCount,
                PageSize = pagination.PageSize,
                CurrentPage = pagination.PageNumber,
                TotalPage = (int)Math.Ceiling(totalCount / (double)pagination.PageSize)
            },
            Models = products
        };
    }
}
