using CMSMicroservice.Domain.Events;
using CMSMicroservice.Domain.Enums;

namespace CMSMicroservice.Application.UserOrderCQ.Commands.CancelOrder;

public class CancelOrderCommandHandler : IRequestHandler<CancelOrderCommand, CancelOrderResponseDto>
{
    private readonly IApplicationDbContext _context;

    public CancelOrderCommandHandler(IApplicationDbContext context)
    {
        _context = context;
    }

    public async Task<CancelOrderResponseDto> Handle(CancelOrderCommand request, CancellationToken cancellationToken)
    {
        // پیدا کردن سفارش
        var order = await _context.UserOrders
            .Include(o => o.Transaction)
            .FirstOrDefaultAsync(o => o.Id == request.OrderId, cancellationToken);
        
        if (order == null)
        {
            throw new NotFoundException(nameof(UserOrder), request.OrderId);
        }
        
        // چک کردن که سفارش قابل لغو باشد
        if (order.DeliveryStatus == DeliveryStatus.Delivered)
        {
            throw new InvalidOperationException("سفارش تحویل داده شده قابل لغو نیست");
        }
        
        if (order.DeliveryStatus == DeliveryStatus.Cancelled)
        {
            throw new InvalidOperationException("این سفارش قبلاً لغو شده است");
        }
        
        // تغییر وضعیت سفارش
        order.DeliveryStatus = DeliveryStatus.Cancelled;
        order.DeliveryDescription = $"لغو شده: {request.CancelReason}";
        
        // اگر درخواست بازگشت پول داریم و پرداخت موفق بوده
        if (request.RefundPayment && 
            order.Transaction != null && 
            order.Transaction.PaymentStatus == PaymentStatus.Success)
        {
            // ایجاد تراکنش استرداد
            var refundTransaction = new Transaction
            {
                Amount = -order.Amount,
                Description = $"بازگشت وجه سفارش {request.OrderId}: {request.CancelReason}",
                PaymentStatus = PaymentStatus.Success,
                PaymentDate = DateTime.UtcNow,
                RefId = $"REFUND-ORDER-{order.Id}",
                Type = TransactionType.Buy
            };
            
            await _context.Transactions.AddAsync(refundTransaction, cancellationToken);
        }
        
        // ثبت Event
        order.AddDomainEvent(new CancelOrderEvent(order, request.CancelReason));
        
        await _context.SaveChangesAsync(cancellationToken);
        
        return new CancelOrderResponseDto
        {
            OrderId = order.Id,
            Status = order.DeliveryStatus,
            Message = "سفارش با موفقیت لغو شد",
            RefundProcessed = request.RefundPayment && order.Transaction != null
        };
    }
}
