using AdsServingService.Infrastructure;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace AdsServingService.API.Application.Queries;

/// <summary>
/// EN: Handler for GetAuctionsQuery.
/// VI: Handler cho GetAuctionsQuery.
/// </summary>
public class GetAuctionsQueryHandler : IRequestHandler<GetAuctionsQuery, PagedResult<AuctionDto>>
{
    private readonly AdsServingServiceContext _context;

    public GetAuctionsQueryHandler(AdsServingServiceContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }

    public async Task<PagedResult<AuctionDto>> Handle(GetAuctionsQuery request, CancellationToken cancellationToken)
    {
        var query = _context.Auctions.AsQueryable();

        // Apply filters
        if (request.UserId.HasValue)
            query = query.Where(a => a.UserId == request.UserId.Value);

        if (!string.IsNullOrEmpty(request.PlacementType))
            query = query.Where(a => a.PlacementType == request.PlacementType);

        if (request.StartDate.HasValue)
            query = query.Where(a => EF.Property<DateTime>(a, "_auctionTime") >= request.StartDate.Value);

        if (request.EndDate.HasValue)
            query = query.Where(a => EF.Property<DateTime>(a, "_auctionTime") <= request.EndDate.Value);

        // Get total count
        var totalCount = await query.CountAsync(cancellationToken);

        // Apply pagination
        var auctions = await query
            .OrderByDescending(a => EF.Property<DateTime>(a, "_auctionTime"))
            .Skip((request.Page - 1) * request.PageSize)
            .Take(request.PageSize)
            .Select(a => new AuctionDto
            {
                Id = a.Id,
                UserId = a.UserId,
                PlacementType = a.PlacementType,
                AuctionTime = EF.Property<DateTime>(a, "_auctionTime"),
                BidCount = a.Bids.Count,
                WinningAdId = a.Result != null ? a.Result.WinningAdId : null,
                FinalPrice = a.Result != null ? a.Result.FinalPrice : null,
                WinningeCPM = a.Result != null ? a.Result.WinningeCPM : null
            })
            .ToListAsync(cancellationToken);

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