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

namespace Grand.Business.Checkout.Queries.Handlers.Orders.Tests
{
    [TestClass()]
    public class HandlerTests
    {
        private Mock<IPaymentService> _paymentServiceMock;

        [TestInitialize()]
        public void Init()
        {
            _paymentServiceMock = new Mock<IPaymentService>();
            _paymentServiceMock.Setup(x => x.SupportCapture(It.IsAny<string>())).Returns(Task.FromResult(true));
            _paymentServiceMock.Setup(x => x.SupportRefund(It.IsAny<string>())).Returns(Task.FromResult(true));
            _paymentServiceMock.Setup(x => x.SupportPartiallyRefund(It.IsAny<string>())).Returns(Task.FromResult(true));
            _paymentServiceMock.Setup(x => x.SupportVoid(It.IsAny<string>())).Returns(Task.FromResult(true));
        }

        [TestMethod()]
        public async Task CanCancelOrderQueryHandler_HandleTest_OrderStatus_Pending_True()
        {
            //Arrange
            var canCancelOrderQueryHandler = new CanCancelOrderQueryHandler();
            //Act
            var result = await canCancelOrderQueryHandler.Handle(new CanCancelOrderQuery() { Order = new Order() { OrderStatusId = (int)OrderStatusSystem.Pending } }, CancellationToken.None);
            //Assert
            Assert.IsTrue(result);
        }
        [TestMethod()]
        public async Task CanCancelOrderQueryHandler_HandleTest_OrderStatus_Processing_False()
        {
            //Arrange
            var canCancelOrderQueryHandler = new CanCancelOrderQueryHandler();
            //Act
            var result = await canCancelOrderQueryHandler.Handle(new CanCancelOrderQuery() { Order = new Order() { OrderStatusId = (int)OrderStatusSystem.Processing } }, CancellationToken.None);
            //Assert
            Assert.IsFalse(result);
        }


        [TestMethod()]
        public async Task CanCaptureQueryHandler_HandleTest_TransactionStatus_Authorized_True()
        {
            //Arrange
            var canCaptureQueryHandler = new CanCaptureQueryHandler(_paymentServiceMock.Object);
            //Act
            var result = await canCaptureQueryHandler.Handle(new CanCaptureQuery() { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Authorized } }, CancellationToken.None);
            //Assert
            Assert.IsTrue(result);
        }
        [TestMethod()]
        public async Task CanCaptureQueryHandler_HandleTest_TransactionStatus_Paid_False()
        {
            //Arrange
            var canCaptureQueryHandler = new CanCaptureQueryHandler(_paymentServiceMock.Object);
            //Act
            var result = await canCaptureQueryHandler.Handle(new CanCaptureQuery() { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Paid } }, CancellationToken.None);
            //Assert
            Assert.IsFalse(result);
        }
        [TestMethod()]
        public async Task CanMarkPaymentTransactionAsAuthorizedQueryHandler_HandleTest_TransactionStatus_Canceled_False()
        {
            //Arrange
            var canMarkPaymentTransactionAsAuthorizedQueryHandler = new CanMarkPaymentTransactionAsAuthorizedQueryHandler();
            //Act
            var result = await canMarkPaymentTransactionAsAuthorizedQueryHandler.Handle(new CanMarkPaymentTransactionAsAuthorizedQuery() { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Canceled } }, CancellationToken.None);
            //Assert
            Assert.IsFalse(result);
        }
        [TestMethod()]
        public async Task CanMarkPaymentTransactionAsAuthorizedQueryHandler_HandleTest_TransactionStatus_Pending_True()
        {
            //Arrange
            var canMarkPaymentTransactionAsAuthorizedQueryHandler = new CanMarkPaymentTransactionAsAuthorizedQueryHandler();
            //Act
            var result = await canMarkPaymentTransactionAsAuthorizedQueryHandler.Handle(new CanMarkPaymentTransactionAsAuthorizedQuery() { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Pending } }, CancellationToken.None);
            //Assert
            Assert.IsTrue(result);
        }
        [TestMethod()]
        public async Task CanMarkPaymentTransactionAsPaidQueryHandler_HandleTest_TransactionStatus_Authorized_True()
        {
            //Arrange
            var canMarkPaymentTransactionAsPaidQueryHandler = new CanMarkPaymentTransactionAsPaidQueryHandler();
            //Act
            var result = await canMarkPaymentTransactionAsPaidQueryHandler.Handle(new CanMarkPaymentTransactionAsPaidQuery() { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Authorized } }, CancellationToken.None);
            //Assert
            Assert.IsTrue(result);
        }
        [TestMethod()]
        public async Task CanMarkPaymentTransactionAsPaidQueryHandler_HandleTest_TransactionStatus_Canceled_False()
        {
            //Arrange
            var canMarkPaymentTransactionAsPaidQueryHandler = new CanMarkPaymentTransactionAsPaidQueryHandler();
            //Act
            var result = await canMarkPaymentTransactionAsPaidQueryHandler.Handle(new CanMarkPaymentTransactionAsPaidQuery() { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Canceled } }, CancellationToken.None);
            //Assert
            Assert.IsFalse(result);
        }

        [TestMethod()]
        public async Task CanPartiallyPaidOfflineQuery_HandleTest_TransactionStatus_Pending_True()
        {
            //Arrange
            var canPartiallyPaidOfflineQueryHandler = new CanPartiallyPaidOfflineQueryHandler();
            //Act
            var result = await canPartiallyPaidOfflineQueryHandler.Handle(new CanPartiallyPaidOfflineQuery() { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Pending, TransactionAmount = 20 }, AmountToPaid = 10 }, CancellationToken.None);
            //Assert
            Assert.IsTrue(result);
        }
        [TestMethod()]
        public async Task CanPartiallyPaidOfflineQuery_HandleTest_TransactionStatus_Paid_False()
        {
            //Arrange
            var canPartiallyPaidOfflineQueryHandler = new CanPartiallyPaidOfflineQueryHandler();
            //Act
            var result = await canPartiallyPaidOfflineQueryHandler.Handle(new CanPartiallyPaidOfflineQuery() { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Paid, TransactionAmount = 20 }, AmountToPaid = 10 }, CancellationToken.None);
            //Assert
            Assert.IsFalse(result);
        }
        [TestMethod()]
        public async Task CanPartiallyRefundOfflineQueryHandler_HandleTest_TransactionStatus_Pending_False()
        {
            //Arrange
            var canPartiallyRefundOfflineQueryHandler = new CanPartiallyRefundOfflineQueryHandler();
            //Act
            var result = await canPartiallyRefundOfflineQueryHandler.Handle(new CanPartiallyRefundOfflineQuery() { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Pending, TransactionAmount = 20 } }, CancellationToken.None);
            //Assert
            Assert.IsFalse(result);
        }
        [TestMethod()]
        public async Task CanPartiallyRefundOfflineQueryHandler_HandleTest_TransactionStatus_Paid_True()
        {
            //Arrange
            var canPartiallyRefundOfflineQueryHandler = new CanPartiallyRefundOfflineQueryHandler();
            //Act
            var result = await canPartiallyRefundOfflineQueryHandler.Handle(new CanPartiallyRefundOfflineQuery() { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Pending, TransactionAmount = 20 } }, CancellationToken.None);
            //Assert
            Assert.IsFalse(result);
        }

        [TestMethod()]
        public async Task CanPartiallyRefundQueryHandler_HandleTest_Paid_True()
        {
            //Arrange
            var canPartiallyRefundQueryHandler = new CanPartiallyRefundQueryHandler(_paymentServiceMock.Object);
            //Act
            var result = await canPartiallyRefundQueryHandler.Handle(new CanPartiallyRefundQuery { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Paid, TransactionAmount = 10 } }, CancellationToken.None);
            //Assert
            Assert.IsTrue(result);
        }
        [TestMethod()]
        public async Task CanPartiallyRefundQueryHandler_HandleTest_Pending_False()
        {
            //Arrange
            var canPartiallyRefundQueryHandler = new CanPartiallyRefundQueryHandler(_paymentServiceMock.Object);
            //Act
            var result = await canPartiallyRefundQueryHandler.Handle(new CanPartiallyRefundQuery { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Pending } }, CancellationToken.None);
            //Assert
            Assert.IsFalse(result);
        }
        [TestMethod()]
        public async Task CanRefundOfflineQueryHandler_HandleTest_Paid_True()
        {
            //Arrange
            var canRefundOfflineQueryHandler = new CanRefundOfflineQueryHandler();
            //Act
            var result = await canRefundOfflineQueryHandler.Handle(new CanRefundOfflineQuery { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Paid, TransactionAmount = 10 } }, CancellationToken.None);
            //Assert
            Assert.IsTrue(result);
        }
        [TestMethod()]
        public async Task CanRefundOfflineQueryHandler_HandleTest_Pending_False()
        {
            //Arrange
            var canRefundOfflineQueryHandler = new CanRefundOfflineQueryHandler();
            //Act
            var result = await canRefundOfflineQueryHandler.Handle(new CanRefundOfflineQuery { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Pending, TransactionAmount = 10 } }, CancellationToken.None);
            //Assert
            Assert.IsFalse(result);
        }
        [TestMethod()]
        public async Task CanRefundQueryHandler_HandleTest_Paid_True()
        {
            //Arrange
            var canRefundQueryHandler = new CanRefundQueryHandler(_paymentServiceMock.Object);
            //Act
            var result = await canRefundQueryHandler.Handle(new CanRefundQuery { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Paid, TransactionAmount = 10 } }, CancellationToken.None);
            //Assert
            Assert.IsTrue(result);
        }
        [TestMethod()]
        public async Task CanRefundQueryHandler_HandleTest_Paid_False()
        {
            //Arrange
            var canRefundQueryHandler = new CanRefundQueryHandler(_paymentServiceMock.Object);
            //Act
            var result = await canRefundQueryHandler.Handle(new CanRefundQuery { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Pending, TransactionAmount = 10 } }, CancellationToken.None);
            //Assert
            Assert.IsFalse(result);
        }
        [TestMethod()]
        public async Task CanVoidOfflineQueryHandler_HandleTest_Authorized_True()
        {
            //Arrange
            var canVoidOfflineQueryHandler = new CanVoidOfflineQueryHandler();
            //Act
            var result = await canVoidOfflineQueryHandler.Handle(new CanVoidOfflineQuery { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Authorized, TransactionAmount = 10 } }, CancellationToken.None);
            //Assert
            Assert.IsTrue(result);
        }
        [TestMethod()]
        public async Task CanVoidOfflineQueryHandler_HandleTest_PartialPaid_False()
        {
            //Arrange
            var canVoidOfflineQueryHandler = new CanVoidOfflineQueryHandler();
            //Act
            var result = await canVoidOfflineQueryHandler.Handle(new CanVoidOfflineQuery { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.PartialPaid, TransactionAmount = 10 } }, CancellationToken.None);
            //Assert
            Assert.IsFalse(result);
        }

        [TestMethod()]
        public async Task CanVoidQueryHandler_HandleTest_Authorized_True()
        {
            //Arrange
            var canVoidQueryHandler = new CanVoidQueryHandler(_paymentServiceMock.Object);
            //Act
            var result = await canVoidQueryHandler.Handle(new CanVoidQuery { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Authorized, TransactionAmount = 10 } }, CancellationToken.None);
            //Assert
            Assert.IsTrue(result);
        }
        [TestMethod()]
        public async Task CanVoidQueryHandler_HandleTest_Paid_Fals()
        {
            //Arrange
            var canVoidQueryHandler = new CanVoidQueryHandler(_paymentServiceMock.Object);
            //Act
            var result = await canVoidQueryHandler.Handle(new CanVoidQuery { PaymentTransaction = new PaymentTransaction() { TransactionStatus = TransactionStatus.Paid, TransactionAmount = 10 } }, CancellationToken.None);
            //Assert
            Assert.IsFalse(result);
        }

    }
}