from decimal import Decimal as D
from unittest import mock

from django.contrib.auth import get_user_model
from django.test import TestCase
from django.urls import reverse

from oscar.core.loading import get_model

import ocyan.core.fender
from ocyan.core.utils import merge_dicts

User = get_user_model()
Basket = get_model("basket", "Basket")
PaymentMethod = get_model("checkout", "PaymentMethod")
ocyan_settings = ocyan.core.fender.config.settings
CHECKOUT_OCYAN_OPTIONS = merge_dicts(
    ocyan_settings, {"shipping": {"enable_charged_shipping": True}}
)


@mock.patch.object(ocyan.core.fender.config, "settings", CHECKOUT_OCYAN_OPTIONS)
class CheckoutPaymentMethodTest(TestCase):
    fixtures = [
        "checkout/auth",
        "checkout/catalogue",
        "checkout/shipping",
        "checkout/paymentmethod",
    ]

    @mock.patch("sorl.thumbnail.templatetags.thumbnail.ThumbnailNodeBase.render")
    def setup_checkout(self, render):
        render.return_value = ""
        henk = User.objects.get(username="henk")
        self.client.force_login(henk)
        self.assertEqual(Basket.objects.count(), 0, "The basket should be empty")

        basket_add_url = reverse("basket:add", args=(1,))
        body = {"quantity": 3}

        response = self.client.post(basket_add_url, body)
        self.assertEqual(
            response.status_code, 302, "Adding an item to a basket should redirect."
        )
        self.assertEqual(
            response["location"],
            reverse("basket:summary"),
            "Adding item to basket should redirect to basket",
        )

        return self.client.get(reverse("checkout:index"))

    def test_payment_method(self):
        # pylint: disable=no-value-for-parameter
        response = self.setup_checkout()
        self.assertContains(response, "Dummy betaling")

    def test_payment_method_minimum(self):
        pm = PaymentMethod.objects.get()
        pm.min_amount = D(400)
        pm.save()
        # pylint: disable=no-value-for-parameter
        response = self.setup_checkout()
        self.assertNotContains(response, "Dummy betaling")

    def test_payment_method_maximum(self):
        pm = PaymentMethod.objects.get()
        pm.max_amount = D(200)
        pm.save()
        # pylint: disable=no-value-for-parameter
        response = self.setup_checkout()
        self.assertNotContains(response, "Dummy betaling")
