namespace WalletService.API.Application.Queries.Payments;

using MediatR;
using WalletService.Domain.AggregatesModel.PaymentAggregate;

/// <summary>
/// EN: Handler for GetPaymentByOrderIdQuery.
/// VI: Handler cho GetPaymentByOrderIdQuery.
/// </summary>
public class GetPaymentByOrderIdQueryHandler : IRequestHandler<GetPaymentByOrderIdQuery, PaymentDto?>
{
    private readonly IPaymentRepository _paymentRepository;
    private readonly ILogger<GetPaymentByOrderIdQueryHandler> _logger;

    public GetPaymentByOrderIdQueryHandler(
        IPaymentRepository paymentRepository,
        ILogger<GetPaymentByOrderIdQueryHandler> logger)
    {
        _paymentRepository = paymentRepository;
        _logger = logger;
    }

    public async Task<PaymentDto?> Handle(
        GetPaymentByOrderIdQuery request,
        CancellationToken cancellationToken)
    {
        _logger.LogInformation(
            "EN: Getting payment for order {OrderId} / " +
            "VI: Lay thanh toan cho don hang {OrderId}",
            request.OrderId);

        var payment = await _paymentRepository.GetByOrderIdAsync(request.OrderId);

        return payment == null ? null : MapToDto(payment);
    }

    private static PaymentDto MapToDto(Payment payment)
    {
        return new PaymentDto(
            payment.Id,
            payment.OrderId,
            payment.Amount,
            payment.Currency,
            payment.GatewayName,
            payment.TransactionId,
            payment.PaymentUrl,
            payment.Status.Name,
            payment.ErrorCode,
            payment.ErrorMessage,
            payment.CreatedAt,
            payment.CompletedAt);
    }
}

/// <summary>
/// EN: Handler for GetPaymentByTransactionIdQuery.
/// VI: Handler cho GetPaymentByTransactionIdQuery.
/// </summary>
public class GetPaymentByTransactionIdQueryHandler : IRequestHandler<GetPaymentByTransactionIdQuery, PaymentDto?>
{
    private readonly IPaymentRepository _paymentRepository;
    private readonly ILogger<GetPaymentByTransactionIdQueryHandler> _logger;

    public GetPaymentByTransactionIdQueryHandler(
        IPaymentRepository paymentRepository,
        ILogger<GetPaymentByTransactionIdQueryHandler> logger)
    {
        _paymentRepository = paymentRepository;
        _logger = logger;
    }

    public async Task<PaymentDto?> Handle(
        GetPaymentByTransactionIdQuery request,
        CancellationToken cancellationToken)
    {
        _logger.LogInformation(
            "EN: Getting payment by transaction ID {TransactionId} / " +
            "VI: Lay thanh toan theo ma giao dich {TransactionId}",
            request.TransactionId);

        var payment = await _paymentRepository.GetByTransactionIdAsync(request.TransactionId);

        if (payment == null) return null;

        return new PaymentDto(
            payment.Id,
            payment.OrderId,
            payment.Amount,
            payment.Currency,
            payment.GatewayName,
            payment.TransactionId,
            payment.PaymentUrl,
            payment.Status.Name,
            payment.ErrorCode,
            payment.ErrorMessage,
            payment.CreatedAt,
            payment.CompletedAt);
    }
}
