import json
import logging
import requests
import uuid

from django.conf import settings

logger = logging.getLogger(__name__)


class EFilingHubCallerBase:

    def __init__(self):
        self.client_id = settings.EFILING_HUB_KEYCLOAK_CLIENT_ID
        self.client_secret = settings.EFILING_HUB_KEYCLOAK_SECRET
        self.token_base_url = settings.EFILING_HUB_KEYCLOAK_BASE_URL
        self.token_realm = settings.EFILING_HUB_KEYCLOAK_REALM
        self.api_base_url = settings.EFILING_HUB_API_BASE_URL
        self.access_token = None
        self.refresh_token = None

    def _get_token(self):
        payload = f'client_id={self.client_id}&grant_type=client_credentials&client_secret={self.client_secret}'
        headers = {'Content-Type': 'application/x-www-form-urlencoded'}

        url = f'{self.token_base_url}/auth/realms/{self.token_realm}/protocol/openid-connect/token'

        response = requests.post(url, headers=headers, data=payload)
        logging.debug('EFH - Get Token %d', response.status_code)
        if response.status_code == 200:
            response = json.loads(response.text)

            # save token as object property..
            if 'access_token' in response:
                self.access_token = response['access_token']
                if 'refresh_token' in response:
                    self.refresh_token = response['refresh_token']

                return True
        return False

    #todo: the MOJ Keycloak instance doesn't have refresh tokens enabled anymore
    def _refresh_token(self):
        if not self.refresh_token:
            return False

        payload = f'client_id={self.client_id}&grant_type=refresh_token&client_secret={self.client_secret}&refresh_token={self.refresh_token}'
        headers = {'Content-Type': 'application/x-www-form-urlencoded'}

        url = f'{self.token_base_url}/auth/realms/{self.token_realm}/protocol/openid-connect/token'

        response = requests.post(url, headers=headers, data=payload)
        logging.debug('EFH - Get Refresh Token %d', response.status_code)

        response = json.loads(response.text)

        # save in session .. lets just assume that current user is authenticated
        if 'access_token' in response:
            self.access_token = response['access_token']
            if 'refresh_token' in response:
                self.refresh_token = response['refresh_token']

            return True
        return False

    def _get_bceid(self, request):

        def _get_raw_bceid(request):
            if hasattr(request, 'user'):
                return request.user.user_guid
            return request.session.get('bcgov_userguid', None)

        guid = _get_raw_bceid(request)
        if guid:
            return str(uuid.UUID(guid))
        return guid

    def _set_headers(self, headers, bceid_guid=None, transaction_id=None):
        if transaction_id:
            headers.update({
                'X-User-Id': bceid_guid,
                'Authorization': f'Bearer {self.access_token}',
                'X-Transaction-Id': transaction_id
            })
        else:
            headers.update({
                'Authorization': f'Bearer {self.access_token}'
            })
        return headers
