// EN: Handler for GetProductsQuery.
// VI: Handler cho GetProductsQuery.

using System.Text.Json;
using MediatR;
using Microsoft.EntityFrameworkCore;
using CatalogService.API.Application.DTOs;
using CatalogService.Infrastructure;

namespace CatalogService.API.Application.Queries;

/// <summary>
/// EN: Handler for querying products with filtering and pagination.
/// VI: Handler query sản phẩm có lọc và phân trang.
/// </summary>
public class GetProductsQueryHandler : IRequestHandler<GetProductsQuery, PagedResult<ProductDto>>
{
    private readonly CatalogContext _context;

    public GetProductsQueryHandler(CatalogContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }

    public async Task<PagedResult<ProductDto>> Handle(GetProductsQuery request, CancellationToken cancellationToken)
    {
        var query = _context.Products
            .Where(p => p.ShopId == request.ShopId);

        // EN: Apply filters
        // VI: Áp dụng bộ lọc
        if (request.IsActive.HasValue)
        {
            query = query.Where(p => p.IsActive == request.IsActive.Value);
        }

        if (!string.IsNullOrWhiteSpace(request.Type))
        {
            query = query.Where(p => p.Type.Name == request.Type);
        }

        // EN: Get total count
        // VI: Lấy tổng số
        var totalCount = await query.CountAsync(cancellationToken);

        // EN: Apply pagination
        // VI: Áp dụng phân trang
        var products = await query
            .OrderBy(p => p.Name)
            .Skip((request.Page - 1) * request.PageSize)
            .Take(request.PageSize)
            .Select(p => new ProductDto
            {
                Id = p.Id,
                ShopId = p.ShopId,
                Name = p.Name,
                Description = p.Description,
                Price = p.Price,
                Type = p.Type.Name,
                Attributes = p.Attributes != null 
                    ? JsonSerializer.Deserialize<Dictionary<string, object>>(p.Attributes.RootElement.GetRawText())
                    : null,
                ImageUrl = p.ImageUrl,
                Sku = p.Sku,
                IsActive = p.IsActive,
                CreatedAt = p.CreatedAt,
                UpdatedAt = p.UpdatedAt
            })
            .ToListAsync(cancellationToken);

        return new PagedResult<ProductDto>
        {
            Items = products,
            TotalCount = totalCount,
            Page = request.Page,
            PageSize = request.PageSize
        };
    }
}
