using AdsBillingService.API.Application.DTOs;
using AdsBillingService.Infrastructure;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace AdsBillingService.API.Application.Queries;

/// <summary>
/// EN: Query to get invoices with optional filtering.
/// VI: Query lấy danh sách hóa đơn với bộ lọc tùy chọn.
/// </summary>
public record GetInvoicesQuery(
    Guid? BillingAccountId = null,
    string? Status = null,
    int PageNumber = 1,
    int PageSize = 20) : IRequest<List<InvoiceDto>>;

/// <summary>
/// EN: Handler for GetInvoicesQuery.
/// VI: Handler cho GetInvoicesQuery.
/// </summary>
public class GetInvoicesQueryHandler : IRequestHandler<GetInvoicesQuery, List<InvoiceDto>>
{
    private readonly AdsBillingServiceContext _context;

    public GetInvoicesQueryHandler(AdsBillingServiceContext context)
    {
        _context = context ?? throw new ArgumentNullException(nameof(context));
    }

    public async Task<List<InvoiceDto>> Handle(GetInvoicesQuery request, CancellationToken cancellationToken)
    {
        var query = _context.Invoices.AsNoTracking();

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

        if (!string.IsNullOrEmpty(request.Status))
        {
            query = query.Where(i => i.Status.ToString() == request.Status);
        }

        var invoices = await query
            .OrderByDescending(i => i.IssueDate)
            .Skip((request.PageNumber - 1) * request.PageSize)
            .Take(request.PageSize)
            .Select(i => new InvoiceDto
            {
                Id = i.Id,
                BillingAccountId = i.BillingAccountId,
                InvoiceNumber = i.InvoiceNumber,
                Status = i.Status.ToString(),
                IssueDate = i.IssueDate,
                DueDate = i.DueDate,
                TotalAmount = i.TotalAmount,
                LineItems = new List<InvoiceLineItemDto>() // EN: Loaded separately / VI: Tải riêng
            })
            .ToListAsync(cancellationToken);

        return invoices;
    }
}
