"""
Payment

cardCheckout(productName: String, amount: String, paymentCard: PaymentCard): Initiate card checkout.

validateCardCheckout(transactionId: String, token: String): Validate a card checkout

bankCheckout(productName: String, amount: String, bankAccount: BankAccount): Initiate bank checkout.

validateBankCheckout(transactionId: String, token: String): Validate a bank checkout

bankTransfer(productName: String, recipients: List<Bank>): Move money form payment wallet to bank account

mobileCheckout(productName: String, phoneNumber: String, amount: String): Initiate mobile checkout.

mobileB2C(productName: String, consumers: List<Consumer>): Send mobile money to consumers.

mobileB2B(productName: String, recipient: Business): Send mobile money to a business.

walletTransfer(productName: String, targetProductCode: Integer, amount: String, metadata: Map<String, String>)

topupStash(productName: String, amount: String, metadata: Map<String, String>)
"""
import africastalking
import unittest
import random
import time
from test import USERNAME, API_KEY

africastalking.initialize(USERNAME, API_KEY)
service = africastalking.Payment


class TestPaymentService(unittest.TestCase):

    def test_mobile_checkout(self):
        res = service.mobile_checkout(product_name='TestProduct', phone_number='+254718769882', currency_code="USD", amount=10)
        assert res['status'] == 'PendingConfirmation'

    def test_mobile_b2c(self):
        consumer = {
            'name': 'Salama',
            'phoneNumber': '+254718769882',
            'currencyCode': 'KES',
            'amount': 892,
            # Optionals
            'reason': service.REASON['SalaryPayment'],
            'providerChannel': '1122',
            'metadata': {}
        }
        res = service.mobile_b2c(product_name='TestProduct', consumers=[consumer])
        assert res['totalValue'] == 'KES 892.0000'

    def test_mobile_b2b(self):
        business = {
            'provider': 'Athena',
            'transferType': 'BusinessToBusinessTransfer',
            'currencyCode': 'KES',
            'amount': 892.78,
            'destinationChannel': 'ABC',
            'destinationAccount': 'DEF',
            # Optionals
            'metadata': {}
        }
        res = service.mobile_b2b(product_name='TestProduct', business=business)
        assert res['status'] == 'Queued'

    def test_mobile_data(self):
        recepient = {
            "phoneNumber":"+254711223344",
            "quantity":10,
            "unit":"GB",
            "validity":"Daily",
            "metadata":{"some":"information"}
        }
        res = service.mobile_data(product_name='TestProduct', recipients=[recipient])
        assert res['status'] == 'Success'

    def test_bank_transfer(self):
        recipient = {
            'bankAccount': {
                'accountNumber': '2342342343',
                'bankCode': service.BANK['FCMB_NG'],
                # Optionals
                'accountName': 'Salama',
            },
            'currencyCode': 'NGN',
            'amount': 89233.89 + random.randint(32, 7783),
            'narration': 'Test transfer',
            # Optionals
            'metadata': {}
        }
        res = service.bank_transfer(product_name='TestProduct', recipients=[recipient])
        assert res['entries'][0]['status'] == 'Queued'

    def test_wallet_transfer(self):
        res = service.wallet_transfer(product_name='TestProduct', target_product_code=2647, currency_code="KES", amount=7732, metadata={'ID': 'ID'})
        assert res['status'] == 'Success'

    def test_topup_stash(self):
        res = service.topup_stash(product_name='TestProduct', currency_code='KES', amount=8732)
        assert res['status'] == 'Success'

    def test_bank_checkout(self):
        bank_account = {
            'accountNumber': '2342342343',
            'bankCode': service.BANK['FCMB_NG'],
            # Optionals
            'accountName': 'Salama',
            'dateOfBirth': '2001-11-21',
        }
        amount = 783 + random.randint(34, 77742)
        res = service.bank_checkout(product_name='TestProduct', currency_code='NGN', amount=amount,
                                    bank_account=bank_account, narration='Hello')
        assert res['status'] == 'PendingValidation'

    def test_validate_bank_checkout(self):
        fake_id = '624241f8' + str(random.randint(34, 43332))
        res = service.validate_bank_checkout(transaction_id=fake_id, otp=4433)
        assert res['status'] == 'InvalidRequest'

    def test_validate_card_checkout(self):
        fake_id = '624241f8' + str(random.randint(34, 43332))
        res = service.validate_card_checkout(transaction_id=fake_id, otp=4433)
        assert res['status'] == 'InvalidRequest'

    def test_card_checkout(self):
        card = {
            'number': '9223372036854775807',
            'cvvNumber': 2233,
            'expiryMonth': 11,
            'expiryYear': 2049,
            'countryCode': 'NG',
            'authToken': '3323'
        }
        amount = 783 + random.randint(34, 77742)
        res = service.card_checkout(product_name='TestProduct', currency_code='NGN', amount=amount,
                                    payment_card=card, narration='Hello')
        assert res['status'] == 'PendingValidation'

    def test_fetch_product_transactions(self):
        product_name='TestProduct'
        res = service.product_transactions('TestProduct')
        assert res['status'] == 'Success'

    def test_fetch_product_transactions_with_filters(self):
        filters = {
            "startDate": "2018-01-01",
            "endDate": "2018-12-31",
            "category": "UserStashTopup",
            "status": "Failed"
        }
        # to prevent throttling
        time.sleep(5)
        res = service.product_transactions('TestProduct', filters)
        assert res['status'] == 'Success'

    def test_find_transaction(self):
        transaction_id = 'ATPid_8b938630c08eb9973e8438291451f76b'
        res = service.find_transaction(transaction_id)
        assert res['status'] == 'Success'

    def test_fetch_wallet_transactions(self):
        res = service.wallet_transactions()
        assert res['status'] == 'Success'

    def test_fetch_wallet_transactions_with_filters(self):
        filters = {
            "startDate": "2018-01-01",
            "endDate": "2018-12-31",
            "categories": "Debit"
        }
        res = service.wallet_transactions()
        assert res['status'] == 'Success'

    def test_fetch_wallet_balance(self):
        res = service.wallet_balance()
        assert res['status'] == 'Success'
        
if __name__ == '__main__':
    unittest.main()
