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

namespace Indotalent.Features.Sales.CreditNote.Cqrs;

public record GetSalesReturnDetailForCreditNoteQuery(string SalesReturnId) : IRequest<GetCreditNoteByIdResponse?>;

public class GetSalesReturnDetailForCreditNoteHandler : IRequestHandler<GetSalesReturnDetailForCreditNoteQuery, GetCreditNoteByIdResponse?>
{
    private readonly AppDbContext _context;
    public GetSalesReturnDetailForCreditNoteHandler(AppDbContext context) => _context = context;

    public async Task<GetCreditNoteByIdResponse?> Handle(GetSalesReturnDetailForCreditNoteQuery request, CancellationToken cancellationToken)
    {
        var salesReturn = await _context.SalesReturn
            .AsNoTracking()
            .Include(x => x.DeliveryOrder)
                .ThenInclude(do_ => do_!.SalesOrder)
                    .ThenInclude(so => so!.Tax)
            .FirstOrDefaultAsync(x => x.Id == request.SalesReturnId, cancellationToken);

        if (salesReturn == null) return null;

        var salesOrder = salesReturn.DeliveryOrder?.SalesOrder;
        var taxRate = salesOrder?.Tax?.PercentageValue ?? 0;

        var transactions = await _context.InventoryTransaction
            .AsNoTracking()
            .Include(x => x.Product)
            .Where(x => x.ModuleId == request.SalesReturnId && x.ModuleName == nameof(Data.Entities.SalesReturn))
            .ToListAsync(cancellationToken);

        var items = new List<CreditNoteItemResponse>();
        decimal subTotal = 0;

        foreach (var trans in transactions)
        {
            var soItem = await _context.SalesOrderItem
                .AsNoTracking()
                .FirstOrDefaultAsync(x => x.SalesOrderId == salesOrder!.Id && x.ProductId == trans.ProductId, cancellationToken);

            var unitPrice = soItem?.UnitPrice ?? 0;
            var qty = Math.Abs(trans.Movement ?? 0);
            var total = unitPrice * (decimal)qty;

            items.Add(new CreditNoteItemResponse
            {
                Id = trans.Id,
                ProductId = trans.ProductId,
                ProductName = trans.Product?.Name,
                UnitPrice = unitPrice,
                Quantity = qty,
                Total = total
            });

            subTotal += total;
        }

        var taxAmount = subTotal * (decimal)(taxRate / 100);

        return new GetCreditNoteByIdResponse
        {
            SalesReturnId = salesReturn.Id,
            SalesReturnNumber = salesReturn.AutoNumber,
            BeforeTaxAmount = subTotal,
            TaxAmount = taxAmount,
            AfterTaxAmount = subTotal + taxAmount,
            Items = items
        };
    }
}