using NUnit.Framework;
using ServiceStack.Stripe;
using ServiceStack.Stripe.Types;
using ServiceStack.Text;

namespace Stripe.Tests
{
    /// <summary>
    /// https://stripe.com/docs/api/curl#subscriptions
    /// </summary>
    [TestFixture]
    public class StripeGatewaySubscriptionTests : TestsBase
    {
        [Test]
        public void Can_Subscribe_Customer()
        {
            var customer = CreateCustomer();
            var coupon = GetOrCreateCoupon();
            var plan = GetOrCreatePlan();

            var subscription = gateway.Post(new SubscribeStripeCustomer
            {
                CustomerId = customer.Id,
                Plan = plan.Id,
                Coupon = coupon.Id,
                Quantity = 1,
            });

            subscription.PrintDump();

            Assert.That(subscription.Id, Is.Not.Null);
            Assert.That(subscription.Customer, Is.EqualTo(customer.Id));
            Assert.That(subscription.Status, Is.EqualTo(StripeSubscriptionStatus.Active));
            Assert.That(subscription.Plan.Id, Is.EqualTo(plan.Id));
            Assert.That(subscription.Quantity, Is.EqualTo(1));
        }

        [Test]
        public void Can_Cancel_Subscription()
        {
            var customer = CreateCustomer();
            var plan = GetOrCreatePlan();

            var subscription = gateway.Post(new SubscribeStripeCustomer
            {
                CustomerId = customer.Id,
                Plan = plan.Id,
                Quantity = 1,
            });

            var cancelled = gateway.Delete(new CancelStripeSubscription
            {
                SubscriptionId = subscription.Id,
                InvoiceNow = true,
                Prorate = true,
            });

            Assert.That(cancelled.Customer, Is.EqualTo(customer.Id));
            Assert.That(cancelled.Id, Is.EqualTo(subscription.Id));
            Assert.That(cancelled.Status, Is.EqualTo(StripeSubscriptionStatus.Canceled));
        }

        [Test]
        public void Can_Cancel_Customer_Subscription()
        {
            var customer = CreateCustomer();
            var plan = GetOrCreatePlan();

            var subscription = gateway.Post(new SubscribeStripeCustomer
            {
                CustomerId = customer.Id,
                Plan = plan.Id,
                Quantity = 1,
            });

            var cancelled = gateway.Delete(new CancelStripeCustomerSubscriptions
            {
                CustomerId = customer.Id,
                AtPeriodEnd = false,
            });

            Assert.That(cancelled.Customer, Is.EqualTo(customer.Id));
            Assert.That(cancelled.Id, Is.EqualTo(subscription.Id));
            Assert.That(cancelled.Status, Is.EqualTo(StripeSubscriptionStatus.Canceled));
        }

        [Test]
        public void Can_Get_Subscription()
        {
            var customer = CreateCustomer();
            var plan = GetOrCreatePlan();

            var subscription = gateway.Post(new SubscribeStripeCustomer
            {
                CustomerId = customer.Id,
                Plan = plan.Id,
                Quantity = 1,
            });

            var retrievedSubscription = gateway.Get(new GetStripeSubscription
            {
                SubscriptionId = subscription.Id
            });

            Assert.That(retrievedSubscription.Customer, Is.EqualTo(customer.Id));
            Assert.That(retrievedSubscription.Id, Is.EqualTo(subscription.Id));
            Assert.That(plan.Id, Is.EqualTo(retrievedSubscription.Plan.Id));
        }
    }
}