import json
from django.conf import settings
from django.shortcuts import render

# Create your views here.
from django.http import JsonResponse
from django.shortcuts import redirect, render
from django.utils.encoding import force_str
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode
from django.contrib.auth.models import User
from django.views import View
from django.contrib.auth import login, authenticate
from django.contrib.sites.shortcuts import get_current_site
from account.myutils import generate_otp, verify_otp
from mailer.sender import send_html_email
from tradewise.settings import EMAIL_HOST_USER as admin_mail
from account.models import Profile
from account.authentication import EmailAuthBackend

from core.models import InvestmentType, Profit
# from core.models import Profit, Transactions
from .tokens import account_activation_token
from django.core.mail import send_mail
from django.template.loader import render_to_string
import traceback
from tradewise.settings import ADMIN_MAIL
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.views.decorators.csrf import csrf_exempt

ADMIN_USER = ADMIN_MAIL

def signup(request):
    profile_id = request.session.get('ref_profile')
    new_user = None
    investment = None
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        email = request.POST['email']
        first_name = request.POST['first_name']
        last_name = request.POST['last_name']
        investment_type = request.POST['investment_type']
        if not User.objects.filter(email=email).exists():
            try:
                new_user = User.objects.create_user(
                    username=username,
                    email=email,
                    password=password,
                    first_name=first_name,
                    last_name=last_name
                )
                new_user.is_active = False
                investment = InvestmentType.objects.create(user=new_user, investment_type=investment_type)
                prof = Profile.objects.create(user=new_user)
                p = Profit.objects.create(user=new_user)
                # p.ref_bonus = 100
                p.save()
                if profile_id is not None:
                    person = Profile.objects.get(id=profile_id)
                    profit = person.user.userprofit
                    profit.ref_bonus += 100
                    profit.save()
                    prof.recomended_by = person.user
                prof.save()
                investment.save()
            except Exception as e:
                umessage = "username already exists"
                print(e)
                if new_user:
                    new_user.delete()
                if investment:
                    investment.delete()
                traceback.print_exc()
                return render(request, "account/register.html", {"umessage": umessage})

            try:
                #  Sending authentication/otp to user
                current_site = get_current_site(request)
                subject = 'Please Activate Your Account'
                # load a template like get_template()
                # and calls its render() method immediately.
                # message = render_to_string('account/activation_request.html', )
                # send_mail(subject=subject, message=message, from_email=admin_mail,recipient_list=[new_user.email], fail_silently=False)
                recipient_list = [new_user.email]
                send_html_email('emails/welcome.html', 'Welcome To InterCapitaStock', admin_mail, recipient_list, context={"user":new_user,
                                                                                                    "token":account_activation_token.make_token(new_user),
                                                                                                    'user': new_user,
                                                                                                    'domain': current_site.domain,
                                                                                                    'uid': urlsafe_base64_encode(force_bytes(new_user.pk)),
                                                                                                    'token': account_activation_token.make_token(new_user),
                                                                                                })
                return redirect('account:activation_sent')
            except Exception as e:
                print(e)
                new_user.delete()
                pmessage = "Error while verifying email. Please try again."
        else:
            pmessage = "Email verification failed. Please try again."
            return render(request, "account/register.html", {"pmessage": pmessage})
    return render(request, "account/register.html")


class ActivateAccountView(View):
    def get(self, request, uidb64, token):
        try:
            uid = force_str(urlsafe_base64_decode(uidb64))
            user = User.objects.get(pk=uid)
        except (TypeError, ValueError, OverflowError, User.DoesNotExist):
            user = None

        if user is not None and account_activation_token.check_token(user, token):
            user.profile.signup_confirmation = True
            user.is_active = True
            user.save()
            send_mail(subject="InterCapitaStock New User", message=f"{user.first_name} {user.last_name} has just signed up..", from_email=admin_mail,
                    recipient_list=[ADMIN_USER], fail_silently=False)
            # login(request, user, backend='django.contrib.auth.backends.ModelBackend')
            login(request, user,  backend='django.contrib.auth.backends.ModelBackend')
            return redirect('core:dashboard')
        else:
            # invalid link
            return render(request, 'activation_invalid.html')


def activation_sent(request):
    # send_mail(subject="InterCapitaStock New User", message=f"{user.first_name} {user.last_name} has just signed up..", from_email=admin_mail,
    #                   recipient_list=[ADMIN_USER], fail_silently=False)
    return render(request, "account/activation-sent.html")


def user_login(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(request, username=username, password=password)

        if user is not None:
            if user.profile.two_factor_enabled:
                otp_code = generate_otp(user)

                # Send OTP via email

                send_html_email('emails/otp.html', 'Intercapitastock OTP-Login', admin_mail, to_emails=[user.email], context={"user":user, "otp":otp_code, "action": "login"})

                # Set session to indicate OTP verification is required
                request.session['otp_user_id'] = user.id
                request.session.set_expiry(1080000)  # Session expires in 3 days (3 days * 24 hours * 60 minutes * 60 seconds)

                return redirect('account:otp_verify')
            else:
                login(request, user, backend='account.authentication.EmailAuthBackend')
                return redirect("core:dashboard")
        else:
            return render(request, 'registration/login.html', {'error': 'Invalid username or password'})

    return render(request, 'registration/login.html',)


@login_required
def update_2fa_status(request):
    if request.method == 'POST':
        user = request.user
        two_factor_enabled = request.POST.get('two_factor_enabled') == 'on'
        request.user.profile.two_factor_enabled = two_factor_enabled
        request.user.profile.save()
        if two_factor_enabled:
            messages.success(request, "Two-factor authentication enabled.")
            send_html_email('emails/2FA.html', 'Two-factor Authentication', admin_mail, [user.email], context={"user":user,})
            # send_mail(subject="InterCapitaStock New User", message=f"Your 2FA has been activated", from_email=admin_mail,
                    # recipient_list=[ADMIN_USER], fail_silently=False)
        else:
            send_html_email('emails/2FA_Disabled.html', 'Two-factor Authentication Disableed', admin_mail, [user.email], context={"user":user,})
            # send_mail(subject="InterCapitaStock New User", message=f"Your 2FA has been de-activated", from_email=admin_mail,
            #         recipient_list=[ADMIN_USER], fail_silently=False)
            messages.success(request, "Two-factor authentication disabled.")
        return redirect('core:dashboard')
    return redirect('core:dashboard')

def getRecProfile(request, *args, **kwargs):
    code = str(kwargs.get('ref_code'))
    if code:
        try:
            profile = Profile.objects.get(ref_code=code)
            request.session['ref_profile'] = profile.id
            print('id', profile.id)
        except Exception as e:
            print(e)
            print("Code doesn't exixt")
    return redirect("account:signup")




def otp_verify_view(request):
    if request.method == 'POST':
        data = json.loads(request.body)
        otp_code = data.get('otp')

        user_id = request.session.get('otp_user_id')

        if not user_id:
            # return render(request, 'account/otp_v.html', {'error': 'Invalid or expired OTP'})
            return JsonResponse({'success': False, 'error': 'User session not found'}, status=400)
            # return redirect('account:login')

        user = User.objects.get(id=user_id)

        if verify_otp(user, otp_code):
            login(request, user, backend='account.authentication.EmailAuthBackend')
            del request.session['otp_user_id']  # Clear OTP session key
            return JsonResponse({'success': True})
            # return redirect('core:dashboard')
        else:
                return JsonResponse({'success': False, 'error': 'Invalid or expired OTP'}, status=400)
            # return render(request, 'account/otp_v.html', {'error': 'Invalid or expired OTP'})

    return render(request, 'account/otp_v.html')


@login_required
def profile(request):
    if request.method == 'POST':
        user = request.user
        profile = request.user.profile
        photo = request.FILES.get('photo', None)
        username = request.POST.get('username', None)
        email = request.POST.get('email', None)

        if photo:
            profile.photo = photo

        if username:
            user.username = username

        if email:
            user.email = email

        user.save()
        profile.save()
    return render(request, "account/profile.html")



def is_ajax(request):
    return request.headers.get('x-requested-with') == 'XMLHttpRequest'