
from decimal import Decimal
from .logic import BasicPayment
from . import PaymentStatus, PurchasedItem, ProviderVariant
from .utils import getter_prefixed_address

__all__ = ["create_test_payment"]

PAYMENT_VARIANTS_API = {
    'default': ('web_payments_dummy.DummyProvider', {}, {}),
    'DummyProvider': ('web_payments_dummy.DummyProvider', {}, {}),
    'DirectPaymentProvider': ('web_payments_externalpayments.DirectPaymentProvider', {}, {}),
    'iban': ('web_payments_externalpayments.BankTransferProvider', {
        "iban": "GL5604449876543210",
        "bic": "DABAIE2D"}, {"localized_name": "iban"}
        ),
    }

def create_test_payment(PAYMENT_VARIANTS_API=PAYMENT_VARIANTS_API, **attributes):
    class TestPayment(BasicPayment):
        id = 523
        pk = id
        description = 'payment'
        currency = 'USD'
        status = PaymentStatus.WAITING
        message = ""
        token = "354338723"
        total = Decimal(100)
        captured_amount = Decimal("0.0")
        extra_data = ""
        variant = "undefined"
        transaction_id = None

        billing_first_name = "John"
        billing_last_name = "Smith"
        billing_address_1 = "JohnStreet 23"
        billing_address_2 = ""
        billing_city = "Neches"
        billing_postcode = "75779"
        billing_country_code = "US"
        billing_country_area = "Tennessee"
        billing_email = "example@example.com"

        get_billing_address = getter_prefixed_address("billing")
        get_shipping_address = get_billing_address

        def __init__(self, **kwargs):
            for key, val in kwargs.items():
                setattr(self, key, val)

        def get_purchased_items(self):
            return [
                PurchasedItem(
                    name='foo', quantity=10, price=Decimal('20'),
                    currency='USD', sku='bar')]

        @staticmethod
        def _list_providers_helper(item):
            _ndict = {"name": item[0]}
            _ndict.update(item[1][2])
            return ProviderVariant(item[1][0], item[1][1], _ndict)

        @classmethod
        def list_providers(cls, **kwargs):
            """ returns an iterable with ProviderVariants """
            if "name" in kwargs:
                if kwargs["name"] in PAYMENT_VARIANTS_API:
                    return [cls._list_providers_helper((kwargs["name"], PAYMENT_VARIANTS_API[kwargs["name"]]))]
                return []
            return map(cls._list_providers_helper, PAYMENT_VARIANTS_API.items())

        def get_provider_variant(self):
            variant_tup = PAYMENT_VARIANTS_API[self.variant]
            variant = ProviderVariant(variant_tup[0], variant_tup[1], {"name": self.variant})
            variant.extra.update(variant_tup[2])
            return variant

        def get_failure_url(self):
            return 'http://cancel.com'

        def get_process_url(self, extra_data=None):
            return 'http://example.com/token'

        def get_success_url(self):
            return 'http://success.com'

        def save(self, **kwargs):
            pass
    # workaround limitation in python
    for key, val in attributes.items():
        setattr(TestPayment, key, val)
    return TestPayment
