from decimal import Decimal
from contextlib import suppress
from urllib.parse import urljoin

import requests
from django.conf import settings


class CurrencyAPIClient:
    CONVERT_ENDPOINT = 'currency/convert'

    MAX_RETRIES = 2

    def __init__(self, api_key: str):
        self.api_url = 'https://api.getgeoapi.com/v2/'
        self.api_key = api_key
        self.session = requests.Session()

    def request(self, method, url, *args, **kwargs):
        params = kwargs.pop('params', {})
        params.update({"api_key": self.api_key})

        joined_url = urljoin(self.api_url, url)
        request = requests.Request(method, joined_url, params=params, *args, **kwargs)

        retries = 0
        while retries < self.MAX_RETRIES:
            retries += 1
            prepared = self.session.prepare_request(request)
            r = self.session.send(prepared, timeout=settings.EXTERNAL_API_TIMEOUT_SEC)

            # TODO: handle/log errors
            return r

    def get_rate(self, currency1: str, currency2: str, amount=1):
        params = {
            'from': currency1,
            'to': currency2,
            'amount': amount,
            'format': 'json'
        }

        r = self.request('GET', self.CONVERT_ENDPOINT, params=params)
        if not r or r.json().get('status') == 'failed':
            return None

        with suppress(KeyError):
            rate = r.json()['rates'][currency2.upper()]['rate']
            return Decimal(rate)

        return None

    def get_cny_rate(self):
        return self.get_rate('cny', 'rub')


client = CurrencyAPIClient(settings.CURRENCY_GETGEOIP_API_KEY)
