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

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

namespace OrderService.API.Application.Commands;

/// <summary>
/// EN: Handler for cancelling an order.
/// VI: Handler hủy order.
/// </summary>
public class CancelOrderCommandHandler : IRequestHandler<CancelOrderCommand, CancelOrderResult>
{
    private readonly IOrderRepository _orderRepository;
    private readonly ILogger<CancelOrderCommandHandler> _logger;

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

    public async Task<CancelOrderResult> Handle(
        CancelOrderCommand request,
        CancellationToken cancellationToken)
    {
        _logger.LogInformation(
            "EN: Cancelling order {OrderId} / VI: Hủy 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: Cancel order (domain validates status)
        // VI: Hủy order (domain validates status)
        order.Cancel(request.Reason);

        // 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 cancelled successfully / VI: Hủy order thành công: {OrderId}, Reason: {Reason}",
            order.Id,
            request.Reason);

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