import json
import traceback
from django.db import connection
from django.contrib.auth.models import Permission, User
from django.contrib.auth.models import User
#from django.shortcuts import get_object_or_404, render_to_response
from django.forms.models import model_to_dict
from django.http import JsonResponse
from django.views.decorators.cache import never_cache
from rest_framework.authentication import BaseAuthentication
from rest_framework import exceptions
from django.core.cache import caches, cache
from datetime import date
import hashlib, os
from django.conf import settings
from Subscriber.models import User, UserAddress
from django.contrib.auth.hashers import check_password, make_password
from Subscriber.serializers import AuthResponseSerializer
from rest_framework.permissions import BasePermission
from django.contrib.gis.geoip2 import GeoIP2
#from .exceptions import InvalidCredentialsError, SubscriptionExpiredError, UserSessionExpiryError
from utility.models import Country



class AuthResponse():
    pass

class StartFitAuthentication(BaseAuthentication):

    def authenticate(self, request):
        #userid = request.data['email']
        #password = request.data['password']
        #loginSubscriber.objects.get()
        #print(request)

        if 'email' in request:
            loginSubs = User.objects.filter(email=request['email'])
            print(loginSubs)
            if len(loginSubs) == 0:
                print("12345")
                resposeArr = {}
                resposeArr['code'] = 200
                resposeArr['result'] = 'False'
                resposeArr['message'] = 'No Such Mail Id Found'
                return resposeArr
            loginSubscriber = User.objects.get(email=request['email'])
            print(loginSubscriber)
            #print(loginSubscriber.password)
            #print(make_password(request['password']))
            #print(loginSubscriber)
            #print(loginSubscriber.id)
            if loginSubscriber is None:
                return JsonResponse({"success":False,"message":"invalid credentials"})
            if 'password' in request:
                if check_password(request['password'], loginSubscriber.password):
                    print("Login validated and succeeded")
                else :
                    print("Invalid Password")
                    resposeArr = {}
                    resposeArr['code'] = 200
                    resposeArr['result'] = 'False'
                    resposeArr['message'] = 'Invalid Password'
                    return resposeArr
            if loginSubscriber.is_active:
                print("Login validated and succeeded")
            else :
                print("Inactive user")
                resposeArr = {}
                resposeArr['code'] = 200
                resposeArr['result'] = 'False'
                resposeArr['is_active'] = 0
                resposeArr['message'] = 'Inactive User'
                return resposeArr
        else:
            loginSubscriber = User.objects.get(email=request)
            print(loginSubscriber,"social Request")
            #print(loginSubscriber.password)
            #print(make_password(request['password']))
            #print(loginSubscriber)
            #print(loginSubscriber.id)
            if loginSubscriber is None:
                return JsonResponse({"success":False,"message":"invalid credentials"})
            if loginSubscriber.is_active:
                print("Login validated and succeeded")
            else :
                print("Invalid Password")
                return JsonResponse({"success":False,"message":"invalid credentials"})
        #print(model_to_dict(loginSubscriber))
        print(loginSubscriber.is_active)
        if  loginSubscriber.is_active:
            session_token = hashlib.sha1(os.urandom(128)).hexdigest()
            try:
                '''print("Before cache set")
                cache = caches['default']
                print("After cache set")'''
                subscriberobj = model_to_dict(loginSubscriber)
                userCountry = UserAddress.objects.filter(user_id =loginSubscriber.id).values('country','id')
                if userCountry.exists():
                    #g = GeoIP2()
                    #ip = request['remote_ip']
                    #if ip:
                    #    country = g.country(ip)['country_name']
                    #else:
                    country = 'India'  # default city
                    countryID = Country.objects.get(name=country)
                    countryID = Country.objects.get(name=country)
                    if loginSubscriber.phoneCode == '' or loginSubscriber.phoneCode == None:
                        updatesubscriber = User.objects.get(id = loginSubscriber.id)
                        updatesubscriber.phoneCode=countryID.dialCode[1:]
                        updatesubscriber.save()
                        subscriberobj['phoneCode'] = updatesubscriber.phoneCode
                    for val in userCountry:
                        valObj = dict(val)
                        if valObj['country'] == '' or valObj['country'] == None:
                            updateaddress = UserAddress.objects.get(id =valObj['id']) 
                            updateaddress.country = countryID.id
                            updateaddress.save()
                            valObj['country'] = countryID.id
                    subscriberobj['userCountry'] = valObj['country']
                else:
                    #g = GeoIP2()
                    #ip = request['remote_ip']
                    #if ip:
                    #    country = g.country(ip)['country_name']
                    #else:
                    country = 'India'  # default city
                    countryID = Country.objects.get(name=country)
                    if loginSubscriber.phoneCode == '' or loginSubscriber.phoneCode == None:
                        updatesubscriber = User.objects.get(id = loginSubscriber.id)
                        updatesubscriber.phoneCode=countryID.dialCode[1:]
                        updatesubscriber.save()
                        subscriberobj['phoneCode'] = updatesubscriber.phoneCode
                    if countryID:
                        userCountry = UserAddress.objects.create(
                            user_id=loginSubscriber.id,
                            country=countryID.id
                        )
                        userCountry.save()
                    else:
                        userCountry = UserAddress.objects.create(
                            user_id=loginSubscriber.id,
                            country=190
                        )
                        userCountry.save()
                    subscriberobj['userCountry'] = userCountry.country
                '''if loginSubscriber.is_superuser is False:
                    userRoleObjs = User.objects.get(user_id = loginSubscriber.id)
                    subscriberobj['role_id'] = userRoleObjs.roles_id'''
                cache.set(session_token, subscriberobj, 1800)
                subsData = cache.get(session_token)
                print("cache Subs Data")
                print(subsData)
                resposeArr = {}
                resposeArr['code'] = 200
                resposeArr['result'] = 'success'
                resposeArr['message'] = 'User logged in successfully'
                resposeArr['sessiontoken'] = session_token
                resposeArr['userDetails'] = subscriberobj
            except:
                traceback.print_exc()
            return resposeArr

        else:
            authresponse = AuthResponse()
            authresponse.code = 200
            loginSubscriber.save()

            return JsonResponse({"success":False,"message":"invalid credentials"})


class SessionAuthentication(BaseAuthentication):
    """
    Overriding Django's session framework for authentication.
    """

    def authenticate(self, request):
        """
        Returns a `Subscriber` if the request session currently has a logged in user.
        Otherwise returns `None`.
        """

        # Get the underlying HttpRequest object
        request = request._request
        print('Header Values')
        print(request.META);
        #user = getattr(request, 'user', None)
        username = None
        #print('str')
        auth_header_value = request.META.get('HTTP_AUTHORIZATION', '')
        print('Auht value ', auth_header_value)
        auth = request.META.get('HTTP_AUTHORIZATION', '').split()
        print(auth,"ll")
        if auth != None and auth != "" and auth !=[]:
            key = auth[0]
        else:
            key = ''
        #key = authentication.get_authorization_header(request)
        #print(key)
        cache = caches['default']
        try:
            username = cache.get(key,None)
            #print(username)
        finally:
            print('entered finally')
            print(username)
            #print('---------------------')
        #except subscriber is None:
        #    print('Exception while retreving object from memcache')
        if username is None:
            #return None
            raise exceptions.NotAuthenticated()
            #raise exceptions.AuthenticationFailed('Invalid token')
        
        cache.set(key, username, settings.SESSION_VALIDITY)

        # Unauthenticated, CSRF validation not required
        if not username or not username['is_active']:
            return None

        #self.enforce_csrf(request)
        request.user = username
        # CSRF passed with authenticated user
        return (username, None)

class IsAuthenticated(BasePermission):

    def has_permission(self, request, view):
        contentSessionUtil = StartFitSessionUtil()
        username = contentSessionUtil.get_user_insession(request)
        print(username)
        if username is None:
            return JsonResponse({"success":False,"message":"Invalid Session"})
            #raise UserSessionExpiryError("Invalid_Session")
        else:
            return JsonResponse({"success":True})

class StartFitSessionUtil():

    def get_user_insession(self, request):
        request = request._request
        #print('authentication')
        #print('-----------')
        #print(request.META.get('HTTP_AUTHORIZATION'))
        #print('------------')
        if request.META.get('HTTP_AUTHORIZATION') is None:
            return None
        auth = request.META.get('HTTP_AUTHORIZATION').split()
        #username = None
        #auth = request.META.get('HTTP_AUTHORIZATION').split()
        if auth != None and auth != "" and auth != [] :
            key = auth[0]
        else:
            key = ""
        #key = authentication.get_authorization_header(request)
        cache = caches['default']
        #print(key)
        try:
            username = cache.get(key,None)
            #print(username)
            if username is None:
                return None
                #return JsonResponse({"success":False,"message":"Invalid Session"})
                #raise UserSessionExpiryError("Invalid_Session")
            else:
                username['sessiontoken'] = key
                return username
        finally:
            print('entered finally')