from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.forms import PasswordResetForm
from django.conf import settings
from django.core.mail import send_mail, EmailMultiAlternatives
from django.utils.html import strip_tags
from django.utils import timezone
from django.http.response import JsonResponse
from django.shortcuts import redirect, render
from django.contrib import messages
from accounts.forms import LoginForm
from .forms import PwdResetForm, RegistrationForm, UserEditForm, CleanForm, UserLoginForm, PwdResetConfirmForm
from .models import UserBase
from stela_control.models import DataEmail
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.encoding import force_bytes, force_str
from .token import account_activation_token
from django.template.loader import render_to_string
from django.contrib.sites.shortcuts import get_current_site
from django.contrib.auth.decorators import login_required
from django.utils.translation import gettext_lazy as _
import re

# Create your views here.
@login_required
def profile_view(request):
    return render(request, 'link-zone/user/profile/profile.html')

def confirm_view(request):

    return render(request, 'accounts/registration/confirmation_email.html')

def account_register(request):
    date = timezone.now()
    if request.method == 'POST':
        registerForm = RegistrationForm(request.POST)
        if registerForm.is_valid():
            user = registerForm.save(commit=False)
            user.email = registerForm.cleaned_data['email']
            user.set_password(registerForm.cleaned_data['password'])
            user.is_active = False
            user.save()
            if UserBase.objects.filter(newsletter=True):
                 data = DataEmail.objects.filter(email=user.email)
                 if data.exists():
                    pass
                 else:
                    DataEmail.objects.create(
                         email = user.email,
                         date = date
                 ) 
            current_site = get_current_site(request)
            subject = _('Activate your account')
            html_content = render_to_string('emails/registration/confirmation.html', {
                        'user': user,           
                        'domain': current_site.domain,
                        'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                        'token': account_activation_token.make_token(user),
                        })
            text_content = strip_tags(html_content)

            email = EmailMultiAlternatives(
                subject,
                text_content,
                settings.DEFAULT_EMAIL,
                [user.email]
            )
            email.attach_alternative(html_content, "text/html")
            email.send()

            subject = _('New User On Your Site')
            html_content = render_to_string('emails/registration/alert.html', {
                        'user': user,           
                        'domain': current_site.domain,
                        'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                        'token': account_activation_token.make_token(user),
                        })
            text_content = strip_tags(html_content)

            email = EmailMultiAlternatives(
                subject,
                text_content,
                settings.STELA_EMAIL,
                [settings.DEFAULT_EMAIL]
            )
            email.attach_alternative(html_content, "text/html")
            email.send()
            
            return redirect('accounts:confirm')

    else:
        registerForm = RegistrationForm()
    return render(request, 'accounts/registration/register.html',{'form':registerForm})

def request(request):
    action = request.POST.get('action')
    print(action)
    
    if action == "checkEmail":
        pattern = re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$')
        email = request.POST.get("user_input")
        if UserBase.objects.filter(email=email).exists():
            response = JsonResponse({'error': _('email not available')})
        elif not pattern.match(email):
            response = JsonResponse({'error': _('Invalid email')})
        else:
            response = JsonResponse({'success': _('email available')})
        return response

    if action == "checkUsername":
        username = request.POST.get("user_input")
        if UserBase.objects.filter(username=username).exists():
            response = JsonResponse({'error': _('username not available')})
            
        elif not re.match(r'^[a-z0-9_]+$', username):
            response = JsonResponse({'error': _('invalid username only lower case, numbers and (_) accepted')})
        
        else:
            response = JsonResponse({'success': _('username available')})
        
        return response
        
    if action == "checkPassword":
        password = request.POST.get("password")
        
        if len(password) < 8:
            response = JsonResponse({'error': _('Password must be at least 8 characters long')})
        
        elif not re.match(r'^[a-zA-Z0-9*.$_]+$', password):
            response = JsonResponse({'error': _('Password must contain only alphanumeric and special characters (a-zA-Z0-9*$_.)')})
        
        elif password.isalpha():
            response = JsonResponse({'error': _('Password must contain at least one number')})
            
        else:
            response = JsonResponse({'success': _('Password is valid')})

        return response

    if action == "matchPassword":
        password1 = request.POST.get("password1")
        password2 = request.POST.get("password2")

        if password1 != password2:
            response = JsonResponse({'error': _('Password dismatch.')})
        else:
            response = JsonResponse({'success': _('Password match')})
        return response
    
def clean_address(request):
    user = request.user
    data = UserBase.objects.get(pk=user.id)
    profile = CleanForm(instance=data)

    event = "Clean Address"

    context={
        'event': event,
        'profile': profile
    }

    return render(request, 'accounts/user/clean_user.html',context)

def addressFormStela(request):
    user = request.user
    data = UserBase.objects.get(pk=user.id)
    profile = CleanForm(instance=data)
    form = CleanForm(request.POST, request.FILES, instance=data)
        
    if form.is_valid():
            form = profile.save(commit=False)
            form.user = user
            form.save()
            form.save(using='master')

            return redirect("http://stela.localhost:8000/cart")

def password_reset(request):
    if request.method == 'POST':
        registerForm = PwdResetForm(request.POST)
        if registerForm.is_valid():
            data = registerForm.cleaned_data['email']
            user_email = UserBase.objects.filter(email=data)
            if user_email.exists():
                for user in user_email:

                    current_site = get_current_site(request)
                    subject = _('Password Reset')
                    html_content = render_to_string('emails/registration/password_reset_email.html', {
                                'user': user,       
                                'email': user.email,    
                                'domain': current_site.domain,
                                'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                                'token': account_activation_token.make_token(user),
                                })
                    text_content = strip_tags(html_content)

                    email = EmailMultiAlternatives(
                        subject,
                        text_content,
                        settings.DEFAULT_EMAIL,
                        [user.email]
                    )
                    email.attach_alternative(html_content, "text/html")
                    email.send()

                    messages.success(request, _('We have sent recovery link.'))
                    return redirect('accounts:password_reset_done')
    else:
        registerForm = PwdResetForm()
        
    return render(request, 'accounts/user/password_reset_form.html',{'form':registerForm})

def new_password_activate(request, uidb64, token):
    try:
        uid = force_str(urlsafe_base64_decode(uidb64))
        user = UserBase.objects.get(pk=uid)
    except Exception as e:
        user = None
        print(e)

    if user is not None and account_activation_token.check_token(user, token):
        if request.method == 'POST':
            form = PwdResetConfirmForm(user, request.POST)
            if form.is_valid():
                form.save()
                messages.success(request, _("Your new password has been set."))
                return redirect('/accounts/login/')
            else:
                for error in list(form.errors.values()):
                    messages.error(request, error)

        form = PwdResetConfirmForm(user)
        return render(request, 'accounts/user/password_reset_done.html', {
            'form': form,
            'call': 'password reset granted'
            })
    else:
        messages.error(request, _("Link is expired"))

    messages.error(request, _('Something went wrong, redirecting back to account login'))
    return redirect('/accounts/login/')

def account_activate(request, uidb64, token):
    try:
        uid = force_str(urlsafe_base64_decode(uidb64))
        user = UserBase.objects.get(pk=uid)
    except:
        pass
    if user is not None and account_activation_token.check_token(user, token):
        user.is_active = True
        user.save()
        login(request, user)
        messages.success(request, 'Your account has been activated.')
        return redirect('linkzone:console')
    else:
        return render(request, 'accounts/registration/activation_invalid.html') 

@login_required
def edit_details(request):

    if request.method == 'POST':
        user_form = UserEditForm(instance=request.user, data=request.POST)

        if user_form.is_valid():
            user_form.save()
    else:
        user_form = UserEditForm(instance=request.user)
    return render(request, 'link-zone/user/profile/edit_details.html', {'user_form': user_form}) 

@login_required
def delete_user(request):
    user = UserBase.objects.get(username=request.user)
    user.is_active = False
    user.save()
    logout(request)
    return redirect('accounts:delete_confirm')

def logout_view(request):
    logout(request)
    return redirect('/accounts/login/')
