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

using MediatR;
using OrderService.API.Application.DTOs;
using OrderService.Domain.AggregatesModel.OrderAggregate;

namespace OrderService.API.Application.Commands;

/// <summary>
/// EN: Handler for creating a return order — validates original order, creates return with negative amounts, restores inventory.
/// VI: Handler cho tạo đơn trả hàng — xác thực đơn gốc, tạo đơn trả với số tiền âm, khôi phục inventory.
/// </summary>
public class CreateReturnCommandHandler : IRequestHandler<CreateReturnCommand, CreateReturnResult>
{
    private readonly IOrderRepository _orderRepository;
    private readonly ILogger<CreateReturnCommandHandler> _logger;

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

    public async Task<CreateReturnResult> Handle(CreateReturnCommand request, CancellationToken cancellationToken)
    {
        _logger.LogInformation(
            "EN: Processing return for order {OriginalOrderId} in shop {ShopId} / VI: Xử lý trả hàng cho đơn {OriginalOrderId} trong shop {ShopId}",
            request.OriginalOrderId, request.ShopId);

        // EN: Validate original order exists and is completed
        // VI: Xác thực đơn hàng gốc tồn tại và đã hoàn thành
        var originalOrder = await _orderRepository.GetByIdAsync(request.OriginalOrderId, cancellationToken);

        if (originalOrder == null)
        {
            return new CreateReturnResult(false, null, null,
                $"Original order {request.OriginalOrderId} not found / Đơn hàng gốc {request.OriginalOrderId} không tìm thấy");
        }

        if (originalOrder.ShopId != request.ShopId)
        {
            return new CreateReturnResult(false, null, null,
                "Order does not belong to this shop / Đơn hàng không thuộc shop này");
        }

        if (originalOrder.Status != OrderStatus.Completed && originalOrder.Status != OrderStatus.Paid)
        {
            return new CreateReturnResult(false, null, null,
                $"Cannot return order with status {originalOrder.Status.Name}. Order must be Completed or Paid / Không thể trả hàng cho đơn có trạng thái {originalOrder.Status.Name}. Đơn phải Hoàn thành hoặc Đã thanh toán");
        }

        // EN: Build a lookup of original order items
        // VI: Xây dựng lookup cho items đơn hàng gốc
        var originalItemsMap = originalOrder.Items.ToDictionary(i => i.Id);

        // EN: Create return order with negative amounts
        // VI: Tạo đơn trả hàng với số tiền âm
        var returnOrder = new Order(request.ShopId, originalOrder.CustomerId);

        decimal refundAmount = 0;

        foreach (var returnItem in request.Items)
        {
            if (!originalItemsMap.TryGetValue(returnItem.OrderItemId, out var originalItem))
            {
                return new CreateReturnResult(false, null, null,
                    $"Order item {returnItem.OrderItemId} not found in original order / Item {returnItem.OrderItemId} không tìm thấy trong đơn hàng gốc");
            }

            if (returnItem.Quantity <= 0 || returnItem.Quantity > originalItem.Quantity)
            {
                return new CreateReturnResult(false, null, null,
                    $"Invalid return quantity for item {returnItem.OrderItemId}. Max: {originalItem.Quantity} / Số lượng trả không hợp lệ cho item {returnItem.OrderItemId}. Tối đa: {originalItem.Quantity}");
            }

            // EN: Create return item with negative unit price for refund calculation
            // VI: Tạo return item với đơn giá âm cho tính toán hoàn tiền
            var orderItem = new OrderItem(
                originalItem.ProductId,
                originalItem.ProductName,
                originalItem.ProductType,
                returnItem.Quantity,
                originalItem.UnitPrice,
                metadata: returnItem.Reason,
                trackInventory: originalItem.TrackInventory);

            returnOrder.AddItem(orderItem);
            refundAmount += returnItem.Quantity * originalItem.UnitPrice;
        }

        // EN: Mark as return and process
        // VI: Đánh dấu là đơn trả hàng và xử lý
        returnOrder.MarkAsValidated();
        returnOrder.ProcessReturn(request.Reason, request.OriginalOrderId);

        _orderRepository.Add(returnOrder);
        await _orderRepository.UnitOfWork.SaveEntitiesAsync(cancellationToken);

        _logger.LogInformation(
            "EN: Return order {ReturnOrderId} created for original order {OriginalOrderId}, refund: {RefundAmount} / VI: Đơn trả hàng {ReturnOrderId} đã tạo cho đơn gốc {OriginalOrderId}, hoàn tiền: {RefundAmount}",
            returnOrder.Id, request.OriginalOrderId, refundAmount);

        return new CreateReturnResult(true, returnOrder.Id, refundAmount, null);
    }
}
