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

namespace AdsBillingService.API.Application.Queries;

/// <summary>
/// EN: Query to get invoice by ID with line items.
/// VI: Query lấy hóa đơn theo ID bao gồm các dòng chi tiết.
/// </summary>
public record GetInvoiceByIdQuery(Guid InvoiceId) : IRequest<InvoiceDto?>;

/// <summary>
/// EN: Handler for GetInvoiceByIdQuery.
/// VI: Handler cho GetInvoiceByIdQuery.
/// </summary>
public class GetInvoiceByIdQueryHandler : IRequestHandler<GetInvoiceByIdQuery, InvoiceDto?>
{
    private readonly AdsBillingServiceContext _context;

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

    public async Task<InvoiceDto?> Handle(GetInvoiceByIdQuery request, CancellationToken cancellationToken)
    {
        var invoice = await _context.Invoices
            .AsNoTracking()
            .Where(i => i.Id == request.InvoiceId)
            .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 = i.LineItems.Select(li => new InvoiceLineItemDto
                {
                    Id = li.Id,
                    CampaignId = li.CampaignId,
                    Description = li.Description,
                    Quantity = li.Quantity,
                    UnitPrice = li.UnitPrice,
                    TotalAmount = li.TotalAmount
                }).ToList()
            })
            .FirstOrDefaultAsync(cancellationToken);

        return invoice;
    }
}
