// EN: Handler for CompleteOrderCommand.
// VI: Handler cho CompleteOrderCommand.

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

namespace OrderService.API.Application.Commands;

/// <summary>
/// EN: Handler for completing an order.
/// VI: Handler hoàn thành order.
/// </summary>
public class CompleteOrderCommandHandler : IRequestHandler<CompleteOrderCommand, CompleteOrderResult>
{
    private readonly IOrderRepository _orderRepository;
    private readonly IPosNotificationService _posNotificationService;
    private readonly ILogger<CompleteOrderCommandHandler> _logger;

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

    public async Task<CompleteOrderResult> Handle(
        CompleteOrderCommand request,
        CancellationToken cancellationToken)
    {
        _logger.LogInformation(
            "EN: Completing order {OrderId} / VI: Hoàn thành order {OrderId}",
            request.OrderId);

        // 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 shop ownership
        // VI: Xác minh quyền sở hữu shop
        if (order.ShopId != request.ShopId)
        {
            throw new DomainException("Order does not belong to this shop");
        }

        // EN: Complete order (domain validates status)
        // VI: Hoàn thành order (domain validates status)
        order.MarkAsCompleted();

        // EN: Save changes (domain events will be dispatched)
        // VI: Lưu thay đổi (domain events sẽ được dispatch)
        await _orderRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation(
            "EN: Order completed successfully / VI: Hoàn thành order thành công: {OrderId}",
            order.Id);

        // EN: Send real-time status change notification / VI: Gửi thông báo thay đổi trạng thái real-time
        try
        {
            await _posNotificationService.NotifyOrderStatusChangedAsync(
                order.ShopId, order.Id, "Processing", order.Status.Name, cancellationToken);
        }
        catch (Exception ex)
        {
            _logger.LogWarning(ex,
                "EN: Failed to send POS notification for order {OrderId} / " +
                "VI: Gửi thông báo POS thất bại cho order {OrderId}",
                order.Id);
        }

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