namespace CMSMicroservice.Application.ProductsCQ.Queries.GetLowStockProducts;

public class GetLowStockProductsQueryHandler : IRequestHandler<GetLowStockProductsQuery, GetLowStockProductsResponseDto>
{
    private readonly IApplicationDbContext _context;
    private readonly ILogger<GetLowStockProductsQueryHandler> _logger;

    public GetLowStockProductsQueryHandler(
        IApplicationDbContext context,
        ILogger<GetLowStockProductsQueryHandler> logger)
    {
        _context = context;
        _logger = logger;
    }

    public async Task<GetLowStockProductsResponseDto> Handle(GetLowStockProductsQuery request, CancellationToken cancellationToken)
    {
        // Query اصلی: محصولاتی که موجودی کمتر یا مساوی آستانه دارند
        var query = _context.Products
            .Where(p => p.RemainingCount <= request.Threshold);

        // فیلتر محصولات انحصاری باشگاه (اگر مشخص شده باشد)
        if (request.IsClubExclusive.HasValue)
        {
            query = query.Where(p => p.IsClubExclusive == request.IsClubExclusive.Value);
        }

        // مرتب‌سازی بر اساس موجودی (کمترین موجودی اول)
        query = query.OrderBy(p => p.RemainingCount)
                    .ThenByDescending(p => p.SaleCount); // محصولات پرفروش اولویت بیشتری دارند

        // شمارش کل
        var totalCount = await query.CountAsync(cancellationToken);

        // Pagination
        var products = await query
            .Skip((request.PageIndex - 1) * request.PageSize)
            .Take(request.PageSize)
            .Select(p => new LowStockProductDto
            {
                Id = p.Id,
                Title = p.Title,
                Price = p.Price,
                Discount = p.Discount,
                RemainingCount = p.RemainingCount,
                SaleCount = p.SaleCount,
                IsClubExclusive = p.IsClubExclusive,
                ImagePath = p.ImagePath,
                ThumbnailPath = p.ThumbnailPath,
                Created = p.Created,
                LastModified = p.LastModified
            })
            .ToListAsync(cancellationToken);

        _logger.LogInformation(
            "Found {Count} low stock products (threshold: {Threshold}, page: {Page})", 
            totalCount, request.Threshold, request.PageIndex);

        var totalPages = (int)Math.Ceiling(totalCount / (double)request.PageSize);
        
        return new GetLowStockProductsResponseDto
        {
            MetaData = new MetaData
            {
                CurrentPage = request.PageIndex,
                TotalPage = totalPages,
                PageSize = request.PageSize,
                TotalCount = totalCount,
                HasNext = request.PageIndex < totalPages,
                HasPrevious = request.PageIndex > 1
            },
            Products = products
        };
    }
}
