using Grand.Business.Checkout.Commands.Handlers.Orders;
using Grand.Business.Core.Commands.Checkout.Orders;
using Grand.Business.Core.Interfaces.Checkout.Orders;
using Grand.Business.Core.Interfaces.Checkout.Payments;
using Grand.Business.Core.Queries.Checkout.Orders;
using Grand.Business.Core.Utilities.Checkout;
using Grand.Domain.Orders;
using Grand.Domain.Payments;
using MediatR;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;

namespace Grand.Business.Checkout.Tests.Commands.Handlers.Orders
{
    [TestClass()]
    public class VoidOfflineCommandHandlerTests
    {
        private VoidOfflineCommandHandler _handler;
        private Mock<IPaymentService> _paymentServiceMock;
        private Mock<IPaymentTransactionService> _paymentTransactionMock;
        private Mock<IOrderService> _orderServiceMock;
        private Mock<IMediator> _mediatorMock;

        [TestInitialize]
        public void Init()
        {
            _mediatorMock = new Mock<IMediator>();
            _orderServiceMock = new Mock<IOrderService>();
            _paymentTransactionMock = new Mock<IPaymentTransactionService>();
            _paymentServiceMock = new Mock<IPaymentService>();

            _handler = new VoidOfflineCommandHandler(
                 _orderServiceMock.Object, _paymentTransactionMock.Object,
                _mediatorMock.Object);
        }

        [TestMethod()]
        public async Task HandleTest()
        {
            //Arrange
            var command = new VoidOfflineCommand { PaymentTransaction = new PaymentTransaction() };
            _mediatorMock.Setup(x => x.Send(It.IsAny<CanVoidOfflineQuery>(), default))
                .Returns(Task.FromResult(true));
            _orderServiceMock.Setup(x => x.GetOrderByGuid(It.IsAny<Guid>())).Returns(Task.FromResult(new Order()));
            _paymentServiceMock.Setup(x => x.Void(It.IsAny<PaymentTransaction>())).Returns(Task.FromResult(new VoidPaymentResult { NewTransactionStatus = TransactionStatus.Voided }));
            _paymentTransactionMock.Setup(x => x.GetById(It.IsAny<string>())).Returns(Task.FromResult(new PaymentTransaction()));
            //Act
            var result = await _handler.Handle(command, CancellationToken.None);
            //Assert
            _orderServiceMock.Verify(c => c.UpdateOrder(It.IsAny<Order>()), Times.Once);
            _paymentTransactionMock.Verify(c => c.UpdatePaymentTransaction(It.IsAny<PaymentTransaction>()), Times.Once);
        }
    }
}