// EN: Handler for CompleteOrderPaymentCommand — finalizes payment after gateway callback.
// VI: Handler cho CompleteOrderPaymentCommand — hoàn tất thanh toán sau callback cổng thanh toán.

using MediatR;
using OrderService.Domain.AggregatesModel.OrderAggregate;
using OrderService.Domain.Exceptions;

namespace OrderService.API.Application.Commands;

/// <summary>
/// EN: Handler for completing order payment after online gateway confirmation.
/// VI: Handler hoàn tất thanh toán order sau xác nhận cổng thanh toán trực tuyến.
/// </summary>
public class CompleteOrderPaymentCommandHandler : IRequestHandler<CompleteOrderPaymentCommand, CompleteOrderPaymentResult>
{
    private readonly IOrderRepository _orderRepository;
    private readonly ILogger<CompleteOrderPaymentCommandHandler> _logger;

    public CompleteOrderPaymentCommandHandler(
        IOrderRepository orderRepository,
        ILogger<CompleteOrderPaymentCommandHandler> logger)
    {
        _orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository));
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
    }

    public async Task<CompleteOrderPaymentResult> Handle(
        CompleteOrderPaymentCommand request,
        CancellationToken cancellationToken)
    {
        _logger.LogInformation(
            "EN: Completing payment for order {OrderId}, success: {IsSuccess}, gateway txn: {GatewayTxnId} / VI: Hoàn tất thanh toán cho order {OrderId}, thành công: {IsSuccess}, giao dịch gateway: {GatewayTxnId}",
            request.OrderId, request.IsSuccess, request.GatewayTransactionId);

        // EN: Load order / VI: Load order
        var order = await _orderRepository.GetByIdAsync(request.OrderId, cancellationToken);
        if (order == null)
        {
            throw new DomainException($"Order not found: {request.OrderId}");
        }

        // EN: Verify order is in PaymentPending status / VI: Xác minh order đang ở trạng thái PaymentPending
        if (order.Status != OrderStatus.PaymentPending)
        {
            _logger.LogWarning(
                "EN: Order {OrderId} is not in PaymentPending status (current: {Status}) / VI: Order {OrderId} không ở trạng thái PaymentPending (hiện tại: {Status})",
                request.OrderId, order.Status.Name);

            return new CompleteOrderPaymentResult(
                false, order.Status.Name,
                $"Order is not awaiting payment (current status: {order.Status.Name})");
        }

        if (!request.IsSuccess)
        {
            // EN: Payment failed — cancel the order
            // VI: Thanh toán thất bại — hủy order
            order.Cancel($"Payment failed: gateway response code {request.GatewayResponseCode}");

            await _orderRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

            _logger.LogWarning(
                "EN: Payment failed for order {OrderId}, order cancelled / VI: Thanh toán thất bại cho order {OrderId}, order đã hủy",
                request.OrderId);

            return new CompleteOrderPaymentResult(false, order.Status.Name, "Payment was not successful");
        }

        // EN: Complete payment and move to processing
        // VI: Hoàn tất thanh toán và chuyển sang đang xử lý
        order.CompletePayment(request.GatewayTransactionId);
        order.MarkAsProcessing();

        await _orderRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation(
            "EN: Payment completed for order {OrderId}, now processing / VI: Thanh toán hoàn tất cho order {OrderId}, đang xử lý",
            order.Id);

        return new CompleteOrderPaymentResult(true, order.Status.Name, null);
    }
}
