import csv
import glob
import os
import time
import dotenv
import requests

from helpers.authorization_fingerprint import authorization_fingerprint
from helpers.tokenization import BrainTreeTokenization
from testcafe.qascripts.helpers import response_data


dotenv.load_dotenv()
CLIENT_ID = os.getenv('RESPONSIVE_CLIENT_ID')
CLIENT_SECRET = os.getenv('CLIENT_SECRET')

folder_path = os.path.dirname(os.path.realpath(__file__))


class GetUserPayment:
    def __init__(self, host):
        self.host = host
        self.query_param = {"client_id": CLIENT_ID}
        self.all_payments_endpoint = "/api/customer/cc"

    def payments_in_wallet(self, user_auth_token):
        url = self.host + self.all_payments_endpoint
        header = {"authorization": user_auth_token}
        try:
            response = requests.get(url, headers=header, params=self.query_param)
            response_contents = response_data.validate_response(response)
            print(response_contents)
            return response_contents
        except Exception as e:
            print(e)

    def get_user_auth_token(self, username, password):
        auth_endpoint = '/api/customer/auth'
        url = self.host + auth_endpoint
        body = {
                'username': username,
                'password': password,
                'g_recaptcha_response': 'null',
                'grant_type': 'password',
                'rememberMe': 'true',
                'scope': 'payment,global',
                'client_secret': CLIENT_SECRET}
        response = requests.post(url=url, params=self.query_param, data=body)
        try:
            if response.ok:
                response_contents = response_data.validate_response(response)
                user_auth = response_contents['access_token']
                return user_auth
            else:
                print(f"could not get {username}'s auth token. Skipping.")
                # return 0
        except Exception as e:
            print(e)


class DeleteCreditCard:
    def __init__(self, host):
        self.query_param = {"client_id": CLIENT_ID}
        self.host = host
        self.credit_card_id = None

    def delete_credit_card(self, payments, user_auth):

        # print(len(payments['cards'] + "are the number of cards on your account"))
        for card_type in payments['cards']:
            if card_type['type'] == 'Mastercard':  # change this as need. If you deleting a visa card change to visa. etc etc.
                self.credit_card_id = card_type['cc_id']

        credit_card_route = f'/api/customer/cc/{self.credit_card_id}'
        credit_card_endpoint = self.host + credit_card_route
        header = {"authorization": user_auth}

        response = requests.delete(credit_card_endpoint, headers=header, params=self.query_param)
        response_data.validate_response(response)
        # print(response_contents)

    def delete_credit_card_from_account(self):
        for filename in glob.glob(os.path.join(folder_path, '*.csv')):
            with open(filename, newline='') as csvfile:
                users = csv.reader(csvfile)
                for user in users:
                    email = ','.join(user)
                    payment = GetUserPayment(self.host)
                    auth = payment.get_user_auth_token(email, '12345')
                    payments_in_wallet = payment.payments_in_wallet(auth)
                    self.delete_credit_card(payments_in_wallet, auth)


class AddCreditCard:
    def __init__(self, host):

        self.nonce_endpoint = '/api/customer/nonce'
        self.user_token_endpoint = '/api/customer/nonce/token'
        self.query_param = {"client_id": CLIENT_ID}
        self.host = host

    def user_payment_token(self, user_auth):
        header = {"authorization": user_auth}

        endpoint = self.host + self.user_token_endpoint
        response = requests.get(endpoint, headers=header, params=self.query_param)
        response = response_data.validate_response(response)
        try:
            client_token = response['client_token']
            hash_token = authorization_fingerprint.decode_user_token(client_token)
            return hash_token
        except TypeError as error:
            print(f'Something is wrong when trying to get the user payment token. I get: {error}')

    def add_credit_card_to_user_account(self, credit_card_token, user_auth):
        url = self.host + self.nonce_endpoint
        header = {"authorization": user_auth}
        # print(user_auth)
        credit_card_body = {
            "default": True,
            "g_recaptcha_response": "null",
            "label": "DCOM CC",
            "storeInVault": True,
            "type": "nonce_creditcard",
            "value": credit_card_token,
        }
        response = requests.post(url, headers=header, json=credit_card_body, params=self.query_param)
        credit_card_response = response_data.validate_response(response)
        print(f'it takes {response.elapsed.total_seconds()} to add a cc to a user account')

        # credit_card_id = credit_card_response
        return credit_card_response

    def add_credit_card_to_account(self):
        payment = GetUserPayment(self.host)

        for filename in glob.glob(os.path.join(folder_path, '*.csv')):
            with open(filename, newline='') as csvfile:
                email_aliases = csv.reader(csvfile)
                for row in email_aliases:
                    email = ','.join(row)
                    auth_token = payment.get_user_auth_token(email, '12345@!')
                    payment_token = self.user_payment_token(auth_token)
                    braintree_object = BrainTreeTokenization(payment_token)
                    braintree_credit_card_token = braintree_object.tokenize_credit_card()
                    self.add_credit_card_to_user_account(braintree_credit_card_token, auth_token)
                    time.sleep(180)


if __name__ == '__main__':
    url = 'https://www.delivery.com'

    user_input = input('What would you like to do? Add or Delete a credit card?: ').lower().strip()
    
    try:
        if user_input == 'add' or user_input == 'a':
            # print("hi this is adding")
            add_card = AddCreditCard(url)
            add_card.add_credit_card_to_account()
        elif user_input == 'delete' or user_input == 'd':
            # print("hi this is deleting ")
            delete_card = DeleteCreditCard(url)
            delete_card.delete_credit_card_from_account()
        else:
            print(f'Please check your input.Either enter "Add" or "Delete"')
    except Exception as e:
        print(e)
