from django.shortcuts import render,redirect
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, get_user_model, login, logout
from django.contrib.auth.decorators import login_required
from mnfapp.models import centralDatabase
from django.core.mail import EmailMessage, EmailMultiAlternatives, message, get_connection
from django.http import HttpResponse, JsonResponse, request, HttpResponseBadRequest
from django.urls import reverse
# from MNF.email import mnfnsendemail
from .models import ReferUser,UserCredentialsForBlockchain,ResetOTP, Wallet
from payment.models import privilegedUser1
from mnfapp.models import Refer, NonAuthenticatedRefer
from Blockchain.utils import walletCreation, decryptionOfPrivate
# from users.tokens import account_activation_token
import json
import random
from django.contrib import messages
from django.contrib.sites.shortcuts import get_current_site
from django.template.loader import render_to_string
from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode
from django.utils.encoding import (force_bytes, force_str)
from .tokens import account_activation_token
import datetime
from rest_framework_simplejwt.tokens import RefreshToken
from .serializers import PasswordResetEmailSerializer,PasswordResetSerializer,VerifyEmailSerializer
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from auto_email.views import sendmail
import uuid
import MNF.settings as setting


def jwt_generator(user):
    refresh = RefreshToken.for_user(user)
    refresh = refresh
    access =  refresh.access_token
    return access, refresh


def registerM(request):
    # profile_id = request.session.get("ref_profile")
    context = {}

    # if request.user.is_active:
    #     context["message3"] = "User is active"
    #     return HttpResponse(json.dumps(context), content_type="application/json")

    if request.method == "POST":
        email = request.POST["email"]
        username = str(request.POST["email"])
        password = request.POST["password"]

        sample = User.objects.all()
        mail_list = []
        user_list = []

        for user in sample:
            mail_list.append(user.email)
        # user_list.append(user.username)
        # if username in user_list:
        #     context["message"] = "Email already exists"
        #     return HttpResponse(json.dumps(context), content_type="application/json")
        # return render(request, "users/signup.html", {"messageses": "username already exists."})
        if email in mail_list:
            context["message"] = "Email already exists"
            return HttpResponse("Email already exists")
            # return render(request,"users/signup.html",{"messageses": "email already exists please try with another email or login."})
        else:

            user = User.objects.create_user(username=username, email=email, password=password)
            user.is_active = False
            user.save()

            if NonAuthenticatedRefer.objects.filter(email=email).exists():

                non_auth_refer_obj = NonAuthenticatedRefer.objects.get(email=email)

                refer_user = ReferUser.objects.filter(non_auth_user_email=email).last()
                if refer_user:
                    refer_user.user = user
                    refer_user.non_auth_user_email = ""
                    refer_user.save()

                privilegedUser1_user = privilegedUser1.objects.filter(email=email).last()
                if privilegedUser1_user:
                    privilegedUser1_user.user = user
                    refer_user.save()

                all_refer_objects = Refer.objects.filter(non_auth_refer=non_auth_refer_obj)

                for refer_obj in all_refer_objects:
                    refer_obj.non_auth_refer = None
                    refer_obj.refer_user = user
                    refer_obj.save()

                non_auth_refer_obj.delete()

            # mail verification code
            # mailverified = MailVerified()
            # if MailVerified.objects.all().exists():
            #     mailverified.id = int(MailVerified.objects.all().last().id) + 1
            # else:
            #     mailverified.id = 1
            # mailverified.user = user
            # mailverified.is_mailVerified = False
            # mailverified.save()
            # manoj verification test end

            # pravesh blockchain
            # blockchain_obj = UserCredentialsForBlockchain()
            # blockchain_obj.user = user
            # blockchain_obj.privateKey = ""
            # blockchain_obj.publicKey = ""
            # blockchain_obj.save()

            # pravesh end


            # x = ReferUser()
            # x.user = user
            # x.referId = str(random.randint(111111, 999999))
            # x.totalRefferals = 0

            if Refer.objects.filter(refer_email1=email):
                # try:
                refer_data = Refer.objects.get(refer_email1=email)
                print("refer data", refer_data)
                x = None
                if refer_data.refer_user_id:
                    try:
                        if centralDatabase.objects.filter(email=email).exists():
                            cd = centralDatabase.objects.get(email=email)
                            cd.user_id = user
                            cd.save()
                        else:
                            cd = centralDatabase()
                            cd.user_id = user
                            cd.email = email
                            cd.save()
                    except:
                        print("An error occurred while accessing the centralDatabase:")

                    referrring_user = User.objects.get(id=refer_data.refer_user_id)
                    x = ReferUser.objects.get(user_id=referrring_user)
                    print("refer referrring_user", referrring_user)

                    key_value = {
                        "User": referrring_user.email,
                        "referredpeople": user.email,
                        "Relevant name": user.email
                    }
                    sendmail(to_email=[referrring_user.email] , email_code='GT5' , key_value=key_value)

                    print("total refer", x)
                    print(x.reffered_by)
                    # x.reffered_by = referrring_user.email
                    x.totalRefferals = x.totalRefferals + 1
                    x.save()
                    # print(x.totalRefferals)
                    if x.totalRefferals == 3:

                        # Pre
                        if privilegedUser1.objects.filter(user=referrring_user, is_active='yes').exists():
                            y = privilegedUser1.objects.get(user=referrring_user, is_active='yes')
                            y.months += 1
                            y.save()
                        # Pre
                        elif privilegedUser1.objects.filter(user=referrring_user, is_active='no').exists():
                            y = privilegedUser1.objects.get(user=referrring_user, is_active='no')
                            y.is_active = 'yes'
                            y.dateSubscribed = datetime.datetime.now()
                            y.months = 1
                            y.save()
                        else:
                            last_instance = privilegedUser1.objects.last()

                            if last_instance is None:
                                initial_id = 1
                            else:
                                initial_id = last_instance.id + 1

                            y = privilegedUser1()
                            y.id = initial_id
                            y.memberType = "normal"
                            y.is_active = 'yes'
                            y.user = referrring_user
                            y.dateSubscribed = datetime.datetime.now()
                            y.months = 1
                            y.save()

                            cd = centralDatabase.objects.get(user_id=referrring_user)
                            cd.priviledgedMember = True
                            cd.save()

                        key_value = {
                                "sender": [username],
                            }
                        sendmail(to_email=[referrring_user.email] , email_code='GT7' , key_value=key_value)
                    # if ReferUser.objects.filter(referId=x.reffered_by).exists():
                    #     pq = ReferUser.objects.get(referId=x.reffered_by)
                    #     pq.referId = pq.referId
                    #     pq.reffered_by = pq.reffered_by
                    #     pq.save()

                if refer_data.non_auth_refer_id:


                    print(refer_data.non_auth_refer_id)
                    print(NonAuthenticatedRefer.objects.get(id=refer_data.non_auth_refer_id))
                    referrring_user = NonAuthenticatedRefer.objects.get(id=refer_data.non_auth_refer_id)
                    print(ReferUser.objects.get(non_auth_user_email=referrring_user.email))

                    x = ReferUser.objects.get(non_auth_user_email=referrring_user.email)
                    print("refer referrring_user", referrring_user)

                    try:
                        if centralDatabase.objects.filter(email=referrring_user.email).exists():
                            cd = centralDatabase.objects.get(email=email)
                            # cd.user_id = user
                            cd.save()
                        else:
                            cd = centralDatabase()
                            cd.firstName, cd.lastName = (referrring_user.name.split(" ", 1) + [""])[:2]
                            cd.contact = referrring_user.phone
                            cd.email = referrring_user.email
                            cd.save()
                    except:
                        print("An error occurred while accessing the centralDatabase:")

                    print("total refer", x)
                    print(x.reffered_by)
                    # x.reffered_by = referrring_user.email
                    x.totalRefferals = x.totalRefferals + 1
                    x.save()
                    print("done", x.totalRefferals)

                    key_value = {
                        "User": referrring_user.email,
                        "referredpeople": user.email,
                        "Relevant name": user.email
                    }
                    # sendmail(to_email=[referrring_user.email] , email_code='GT5' , key_value=key_value)

                    if x.totalRefferals == 3:
                        print("here")
                        # Pre
                        if privilegedUser1.objects.filter(email=referrring_user.email, is_active='yes').exists():
                            y = privilegedUser1.objects.get(email=x.reffered_by, is_active='yes')
                            y.months += 1
                            y.save()
                        # Pre
                        elif privilegedUser1.objects.filter(email=referrring_user.email, is_active='no').exists():
                            y = privilegedUser1.objects.get(email=referrring_user.email, is_active='no')
                            y.is_active = 'yes'
                            y.dateSubscribed = datetime.datetime.now()
                            y.months = 1
                            y.save()
                        else:
                            last_instance = privilegedUser1.objects.last()

                            if last_instance is None:
                                initial_id = 1
                            else:
                                initial_id = last_instance.id + 1

                            y = privilegedUser1()
                            y.id = initial_id
                            y.memberType = "normal"
                            y.is_active = 'yes'
                            y.dateSubscribed = datetime.datetime.now()
                            y.months = 1
                            y.name = referrring_user.name
                            y.phone = referrring_user.phone
                            y.email = referrring_user.email
                            y.save()

                            try:
                                cd = centralDatabase.objects.get(email=referrring_user.email)
                                cd.priviledgedMember = True
                                cd.save()
                            except:
                                print("user not authenticated")

                        key_value = {
                            "sender": [username],
                        }
                        # sendmail(to_email=[referrring_user.email] , email_code='GT7' , key_value=key_value)

                    # if ReferUser.objects.filter(referId=x.reffered_by).exists():
                    #     pq = ReferUser.objects.get(referId=x.reffered_by)
                    #     pq.referId = pq.referId
                    #     pq.reffered_by = pq.reffered_by
                    #     pq.save()


                # except:
                #     print("Some Error")

            # current_site = get_current_site(request)
            site = setting.CSRF_TRUSTED_ORIGINS
            mail_subject = 'Activate Your Account'
            uid = urlsafe_base64_encode(force_bytes(user.pk))
            token = account_activation_token.make_token(user)
            message = render_to_string('users/accountVerification.html', {
                'user': request.user,
                'site' : site,
                # 'domain': current_site.domain,
                'uid': uid,
                'token': token,
            })
            connection = get_connection(
                host=setting.smtp_host, 
                port=setting.smtp_port, 
                username=setting.smtp_username,
                password=setting.smtp_password, use_tls=True
            )
            
            to_email = email
            email = EmailMessage(mail_subject, message, to=[to_email], connection=connection)
            email.send()

            context["message2"] = "A link to verify your account has been sent to your email address. Please verify to enjoy using services on MyNextFilm. Also, check your spam folder if you do not see a mail in your inbox."
            return HttpResponse("A link to verify your account has been sent to your email address. Please verify to enjoy using services on MyNextFilm. Also, check your spam folder if you do not see a mail in your inbox.")
            # messageses = "Registration Successful. Please login."
            # user = authenticate(request, username=username, password=password)
            # if user is not None:
            #     login(request, user)
            #     if request.POST.get("next"):
            #         return redirect(request.POST.get("next"))
            #     else:
            #         # messages.success(request, "Logged In Successfully")
            #         return redirect("base")
            # # return render(request, 'users/signin.html',{'messageses':messageses})
    else:
        messages.warning(request, "Error occurred. Please Try Again")
        return redirect("signup")


def signup(request):
    if request.user.is_authenticated:
        return redirect("/members-home")

    return render(request, "prelogin/home.html")


def activateM(request, uidb64, token):
    context2 = {}
    try:
        print('uuid',uidb64)
        uid = force_str(urlsafe_base64_decode(uidb64))
        print('user id',uid)
        user = User.objects.get(pk=uid)
    except (TypeError, ValueError, OverflowError, User.DoesNotExist):
        user = None
    print("Hello I am here", user, account_activation_token.check_token(user, token))
    print("uid and token during activation", uidb64, token)
    if user is not None and account_activation_token.check_token(user, token):
        print("Activation started")
        user.is_active = True
        email = user.email
        username = user.username
        # login(request, user)
        user.save()

        # # mail verified turns to True
        # x = MailVerified.objects.get(user=user)
        # x.is_mailVerified = True
        # x.save()

        #  pravesh
        # blockchain_created = False
        print("User Saved")
        if UserCredentialsForBlockchain.objects.filter(user=user).exists():
            print("Blockchain Exists")
            blockchain_obj = UserCredentialsForBlockchain.objects.get(user=user)
            print(":::::::::::::::::::::::::::::::::",blockchain_obj.privateKey)
        else:
            print("Blockchain not Exists")
            accountDetail = walletCreation()
            binaryToHex = accountDetail[1]
            blockchain_obj = UserCredentialsForBlockchain()
            blockchain_obj.user = user
            blockchain_obj.privateKey = binaryToHex.hex()
            blockchain_obj.publicKey = accountDetail[0]
            blockchain_obj.save()
            blockchain_created = True
        print("Out of Blockchain Func")

        '''
        x = UserCredentialsForBlockchain.objects.get(user=request.user)

        '''
        if blockchain_created == True:
            print("Blochain Email called")
            privatekey = decryptionOfPrivate(binaryToHex.hex())
            to_email = [email]
            email_code = 'BL2'
            key_value = {
                "public key":accountDetail[0],
                "private key":privatekey.decode('utf-8'),
                # "Transaction Hash":""
            }
            # filePath = “file/path”

            sendmail(to_email=to_email , email_code=email_code , key_value=key_value)


        # subject = "That's a giant leap forward."
        # from_email = settings.EMAIL_HOST_USER
        # to = email
        # context = {"Name": username}
        # mnfnsendemail(
        #     to, subject, "users/templates/users/MR1.html", context, from_email
        # )



        context2[
            "successmessage"
        ] = "Thank you for your email confirmation. Now you can login your account."
        if blockchain_created ==True:
            context2["Wallet_creation"] = "Congratulations! Your wallet has been successfully created."
        return redirect('auth_loginM')
    else:
        context2["successmessage"] = "Activation link is invalid!"
        return HttpResponseBadRequest()


def auth_loginM(request):
    context = {}
    # sendmail(to_email=[request.POST["username"]], email_code="MR1" )

    '''
    # mail verification test
    emailverified = False
    try:
        check = MailVerified.objects.get(user=request.user)
        if check.is_mailVerified:
            emailverified = True
        else:
            emailverified = False
    except:
        emailverified = True
    # mail verification test end

    if request.user.is_active and emailverified:
        context["message1"] = "success"
        return HttpResponse(json.dumps(context), content_type="application/json")
    '''

    if request.method == "POST":
        password = request.POST["password"]
        # user_in = User.objects.get(username = username)
        sample = User.objects.all()
        mail_list = []
        user_list = []
        user_dict = {}
        for user in sample:
            mail_list.append(user.email)
            user_list.append(user.username)
            user_dict[user.email] = user.username
        username = user_dict.get(str(request.POST["username"]))
        if username in user_list:
            user_in = User.objects.get(username=username)

            # mail verification test
            emailverified = True

            # sendmail(to_email=[user_in.email], email_code="MR1" )

            # try:
                # mailgverify = MailVerified.objects.get(user=user_in)
                # if mailgverify.is_mailVerified:
                #     emailverified = True
                # else:
                #     emailverified = False
            # except:
                # emailverified = True
            if request.user.is_active and emailverified:
                context["message1"] = "success"
                return HttpResponse(json.dumps(context), content_type="application/json")

            if user_in.is_active == False or not emailverified:
                # if user_in not emailverified:
                print("ok")
                context["message2"] = "Account verification pending.\nPlease check your registered email and click on the link we have sent.\n please check spam in case you don't find in inbox."
                return HttpResponse(json.dumps(context), content_type="application/json")
            else:
                user = authenticate(
                    request, username=username, password=password)
                if user is not None:
                    if user.last_login is None:
                        sendmail(to_email=[user.email], email_code="MR1")
                    login(request, user)
                    context["message3"] = "login"
                    if "next" in request.POST:
                        context["next"] = request.POST["next"]
                    return HttpResponse(json.dumps(context), content_type="application/json")
                else:
                    try:
                        if User.objects.get(email=request.POST["username"]):
                            pass
                    except:
                        context["message4"] = "Email id not found"
                        return HttpResponse(json.dumps(context), content_type="application/json")
                    if User.objects.get(email=request.POST["username"]).has_usable_password():
                        context["message5"] = "Email or Password is Incorrect"
                        return HttpResponse(json.dumps(context), content_type="application/json")
                    else:
                        context["message6"] = "You are already signed in with this Google ID. Please login with google."
                        return HttpResponse(json.dumps(context), content_type="application/json")
        else:
            context["message7"] = "Invalid email id or password"
            return HttpResponse(json.dumps(context), content_type="application/json")
    else:
        return render(request, "prelogin/home.html", {})

@login_required(login_url='/PersonalLogin-2')
def base(request, **kwargs):

    context = {}

    # if user joins with google then we have to create one object in central Database also.
    if (
        not request.user.is_anonymous
        and not centralDatabase.objects.filter(user_id=request.user)
    ):
        cd = centralDatabase()
        cd.user_id = request.user
        cd.email = request.user.email
        cd.save()



    if not request.user.is_anonymous:
        context["cd"] = centralDatabase.objects.get(user_id=request.user)
        access, refresh = jwt_generator(request.user)
        context["access"] = access
        context["refresh"] = refresh

    if kwargs.get("message"):
        context[
            "messageR"
        ] = "Thanks for refering your friends. You will get extra one month of our services for every 3 joinings from your referal link"
        print('line 401', context)
        return render(request, "prelogin/landing.html", context)
    else:
        if request.session.get("message"):
            msg = request.session.get("message")
            print(msg)
            context["messageR"] = msg
            print("context%%%%%%%%%%%%%%%", context)
            del request.session["message"]
        elif request.session.get("affmessage"):
            msg = request.session.get("affmessage")
            context["messageR"] = msg
            del request.session["affmessage"]
            sendmail(to_email=[request.user.email], email_code="GT8" )
            print('line 415', context)
            return render(request, "mnfapp/landing.html", context)
        # context["messageR"] = 'Submitted Successfully'
        # print('++++++++++++++', context)
    # sendmail(to_email=[request.user.email], email_code="MR1" )
    print('line 420', context)
    return render(request, "mnfapp/landing.html", context)

class SendPasswordResetEmailView(APIView):
    def post(self, request, format=None):
        serializer = PasswordResetEmailSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response({'message': 'Password Reset OTP send. Please check your Email','email':serializer.data['email']}, status=status.HTTP_200_OK)

class OTPVerifyView(APIView):
    def post(self, request):
        sr = VerifyEmailSerializer(data=request.data)
        if sr.is_valid(raise_exception=True):
            if ResetOTP.objects.filter(otp=sr.data['code']):
                obj = ResetOTP.objects.get(otp=sr.data['code'])
                # obj.otp = ''
                obj.uid = self.recovery_code()
                obj.save()
                context = {
                    'message': 'code verified successfully',
                    'recovery_token': obj.uid
                }
                return Response(context, status=status.HTTP_202_ACCEPTED)
            return Response({'status': 'invalid code'}, status=status.HTTP_400_BAD_REQUEST)

    def recovery_code(self):
        while True:
            uid = uuid.uuid4()
            if ResetOTP.objects.filter(uid=uid).exists():
                continue
            return uid



class PasswordResetView(APIView):
    def post(self, request):
        sr = PasswordResetSerializer(data=request.data)
        if sr.is_valid(raise_exception=True):
            if ResetOTP.objects.filter(uid=sr.data['token']):
                obj = ResetOTP.objects.get(uid=sr.data['token'])
                user = obj.user
                user.set_password(sr.data['password'])
                user.save()
                obj.delete()
                context = {
                    'message': 'password updated successfully '
                }
                return Response(context, status=status.HTTP_200_OK)
            return Response({'status': 'invalid code'}, status=status.HTTP_400_BAD_REQUEST)

def user_logout(request):
    # if not request.user.is_authenticated:
    #     return HttpResponseBadRequest()
    logout(request)
    return redirect('/')


def update_balance(val1):
    wall = Wallet.objects.get(user=val1)
    wall.balance = wall.im_balance+wall.mm_balance+wall.lpp_balance
    wall.save()