using Indotalent.ConfigBackEnd.Extensions;
using Indotalent.Infrastructure.Database;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace Indotalent.Features.Sales.PaymentReceiveReport.Cqrs;

public record GetPaymentReceiveReportListDto
{
    public string? Id { get; init; }
    public string? Number { get; init; }
    public DateTime? PaymentDate { get; init; }
    public string? PaymentMethodName { get; init; }
    public decimal? PaymentAmount { get; init; }
    public string? StatusName { get; init; }
    public string? InvoiceNumber { get; init; }
    public string? CustomerName { get; init; }
}

public record GetPaymentReceiveReportListQuery() : IRequest<List<GetPaymentReceiveReportListDto>>;

public class GetPaymentReceiveReportListHandler : IRequestHandler<GetPaymentReceiveReportListQuery, List<GetPaymentReceiveReportListDto>>
{
    private readonly AppDbContext _context;

    public GetPaymentReceiveReportListHandler(AppDbContext context)
    {
        _context = context;
    }

    public async Task<List<GetPaymentReceiveReportListDto>> Handle(GetPaymentReceiveReportListQuery request, CancellationToken cancellationToken)
    {
        var results = await _context.PaymentReceive
            .AsNoTracking()
            .Include(x => x.PaymentMethod)
            .Include(x => x.Invoice)
                .ThenInclude(x => x!.SalesOrder)
                    .ThenInclude(x => x!.Customer)
            .OrderByDescending(x => x.PaymentDate)
            .Select(x => new GetPaymentReceiveReportListDto
            {
                Id = x.Id,
                Number = x.AutoNumber,
                PaymentDate = x.PaymentDate,
                PaymentMethodName = x.PaymentMethod != null ? x.PaymentMethod.Name : string.Empty,
                PaymentAmount = x.PaymentAmount,
                StatusName = x.Status.GetDescription(),
                InvoiceNumber = x.Invoice != null ? x.Invoice.AutoNumber : string.Empty,
                CustomerName = (x.Invoice != null && x.Invoice.SalesOrder != null && x.Invoice.SalesOrder.Customer != null)
                                ? x.Invoice.SalesOrder.Customer.Name : string.Empty
            })
            .ToListAsync(cancellationToken);

        return results;
    }
}