from django.shortcuts import render, redirect

# Import User
from django.contrib.auth.models import User

# Import Integrity Error
from django.db import IntegrityError # occurs when there is an attempt to insert or update data that violates constraints such as unique constraints, foreign key constraints, or other database-specific constraints.

#For messages
from django.contrib import messages

#Importing the django login authentifications
from django.contrib.auth import login , logout
from django.http import JsonResponse
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404
from django.contrib.auth import authenticate, update_session_auth_hash


# Iportant to serialize your data to a form understandable by rest frameworks.
#from .serlializers import NoteSerializer
from rest_framework import serializers

# Codes for rest_framework installation
from rest_framework import status, viewsets
from rest_framework.permissions import AllowAny
from rest_framework.decorators import action
from django.http import HttpResponse

#For Model Importations
from .models import Profile, BlogPost, Category, Tag, Jobs

#For Forms Importations
from .forms import SignupForm,BlogPostForm, JobForm

#Importing the secret parameters
from decouple import config

#FOR REDIRECT FROM ROOT
from rest_framework.views import APIView
from django.http import Http404


#For handling Emails
from django.core.mail import send_mail
from django.template.loader import render_to_string
from django.conf import settings
import json
import re

class DummySerializer(serializers.Serializer):
    #I will add some data later on...
    pass


 

class VictoriaDefaultPage(viewsets.ModelViewSet): 
      
    @action(detail=False, methods=['get'], url_path='')
    def default_page(self, request, *args, **kwargs):
        base_domain = request.build_absolute_uri('/')
        # Check if the user is authenticated
        if request.user.is_authenticated:
            # Redirect authenticated users to the home page
            #return redirect('/home')  # Replace '/omoca/home_page/' with your actual home page URL
             
             return render(request, 'index.html',{'base_domain':base_domain})
         
        else:
            # Redirect non-authenticated users to the login page

            return render(request, 'index.html',{'base_domain':base_domain})

        
class VictoriaViewSet(viewsets.ModelViewSet):
    permission_classes = (AllowAny,)
    serializer_class = DummySerializer
    
    
    @action(detail=False, methods=['get', 'POST'])
    def signup(self, request):
        base_domain = request.build_absolute_uri('/')
        
        if request.method == 'POST':
            form = SignupForm(request.POST)
            
            if form.is_valid():
                email = form.cleaned_data['email']
                username = form.cleaned_data['email']
                password = form.cleaned_data['password1']
                
                # Check if email already exists
                if User.objects.filter(email=email).exists():
                    emailError = "The email already exists"
                    return render(request, 'signup.html', {'form': form, 'emailError': emailError, 'base_domain':base_domain})

                try:
                    # Create user
                    user = User.objects.create_user(
                        email=email,
                        password=password,
                        username=username
                    )
                    # Create user profile
                    profile = Profile.objects.create(
                        user=user,
                        full_name=form.cleaned_data['full_name'],
                        email=email,
                    )
                    profile.save()
                    
                    # Redirect to login page after successful signup
                    return redirect(f'{base_domain}admin_login/')   # You could change the URL to just 'login' instead of the full URL.

                except IntegrityError as e:
                    # Handle any exceptions such as unique constraints on email
                    print(f"Error in credentials verification {e}")
                    # Optionally, add an error message to the form here
            else:
                # In case form is not valid, return form with error messages
                return render(request, 'signup.html', {'form': form, 'emailError': "",'base_domain':base_domain})

        else:
            form = SignupForm()
            return render(request, 'signup.html', {'form': form, 'emailError': "", 'base_domain':base_domain})
     
            
    @action(detail=False, methods=['get', 'POST'])
    def admin_login(self, request):
     base_domain = request.build_absolute_uri('/')
     
        
     if request.method == "POST":
        email = request.POST['email']
        password = request.POST['password']
        if email and password:
         user = User.objects.filter(email=email).first()
         if user:
            if user.check_password(password):
                login(request, user, backend='django.contrib.auth.backends.ModelBackend')
                return redirect(f'{base_domain}home/') #Should redirect to this view.
            else:
                return render(request , 'login.html', {'form': "Invalid password", 'base_domain':base_domain})
         else:
            return render(request , 'login.html', {'form': "Invalid email or password",'base_domain':base_domain})
             
     else:
         return render(request , 'login.html', {'form': "", 'base_domain':base_domain})
    
    
    #@method_decorator(login_required, name='dispatch')  
    @action(detail=False, methods=['get'])
    def home(self, request):
      base_domain = request.build_absolute_uri('/')
      
      user = request.user 
      return render(request, 'index.html',{'base_domain':base_domain})
  
  
  
  
    @method_decorator(login_required, name='dispatch')  
    #ADMIN ONLY
    @action(detail=False, methods=['get','POST'])
    def adminblog(self, request):
        categories = Category.objects.all()
        if request.method == "POST":
            form = BlogPostForm(request.POST, request.FILES)
            
            if form.is_valid():
                
                # Save the form data to create the blog post
                blog_post = form.save(commit=False)
                blog_post.author = request.user  # Automatically set the logged-in user as the author
                blog_post.save()
                
                # Handle categories, tags, and other many-to-many fields
                form.save_m2m()  # Save many-to-many relationships (tags, categories)
                
                print("Blog post submitted successfully!")
                
                # Redirect to the blog post page or the success page
                #return render(request, 'blog.html', {'slug': blog_post.slug})
                return redirect('https://testing.victoriavisaconsultants.com/blog/')

            else:
                # Handle form errors and display them to the user
                print("Form is not valid. Please check the form fields.")
                error = form.errors
                print(form.errors)  # Log the form errors for debugging
                
                # Return the same page with form errors and existing input
                return render(request, 'admin-blogpost.html', {'form': form, 'error': error})
        else:
            
            get_name = Profile.objects.filter(email=request.user).values()
            form = BlogPostForm()

        return render(request, 'admin-blogpost.html', {
            'form': form,
            'name':get_name[0]['full_name'],
            'categories': categories,
        })
  
  
  
    #@method_decorator(login_required, name='dispatch')  
    @action(detail=False, methods=['get'])
    def blog(self, request):
      user = request.user 
      blogs = BlogPost.objects.all().order_by('-timestamp')
      popular_blogs = BlogPost.objects.filter(is_popular=True).order_by('-timestamp')
      base_domain = request.build_absolute_uri('/')
      is_blog_page = True
      
        
      #This is what an admin will see
      if request.user.is_authenticated:
         addBlog = True
          
         return render(request, 'blog.html', {'blogs': blogs, 'addBlog': addBlog, 'popular_blogs': popular_blogs,'base_domain':base_domain, 'is_blog_page': is_blog_page })
     
      
      #These are the users of the system.
      else:
          
        addBlog = False
        return render(request, 'blog.html', {'blogs': blogs, 'popular_blogs': popular_blogs, 'base_domain':base_domain})
  
  
  
      #@method_decorator(login_required, name='dispatch')  
    
    
    @action(detail=False, methods=['get'], url_path=r'blog/(?P<slug>[-\w]+)')
    def singleblog(self, request, slug):
        base_domain = request.build_absolute_uri('/')

        
        try:
            blog_post = BlogPost.objects.get(slug=slug)
            blogs = BlogPost.objects.all().order_by('-timestamp')[:4]
            name_of_author = Profile.objects.filter(email=blog_post.author).values()

            
        except BlogPost.DoesNotExist:
            
            raise Http404("Blog post not found")

        # Pass the blog post details to the template
        context = {
            'title': blog_post.title,
            'sub_title': blog_post.sub_title,
            'slug': blog_post.slug,
            'timestamp': blog_post.timestamp,
            'content': blog_post.content,
            'featured_image': blog_post.featured_image,
            'author': name_of_author[0]['full_name'],
            'tags': blog_post.tags.all(),
            'categories': blog_post.categories.all(),
            'video_url': blog_post.video_url,
            'analytics_code': blog_post.analytics_code,
            'blogs': blogs,  # Add the list of recent blog posts to context
            'base_domain':base_domain
        }
        
        # Render the blog post template with the context
        return render(request, 'single_blog.html',context )

  
    #@method_decorator(login_required, name='dispatch')  
    @action(detail=False, methods=['get'])
    def eligibility(self, request):
      print("Test to see if am eligible")  
      user = request.user 
      return render(request, 'credit_score.html')
  
  
    @method_decorator(login_required, name='dispatch')
    @action(detail=False, methods=['get','post'])
    def adminjobsupdate(self, request):
        if request.method == 'POST':
            form = JobForm(request.POST)
            if form.is_valid():
                # Save the job data to the database
                
                print("Form is in good hands")
                form.save()
                messages.success(request, 'Job has been added successfully!')    
                return redirect('https://testing.victoriavisaconsultants.com/blog/') # You can redirect to a job list or admin page after saving.
            else:
                messages.error(request, 'There was an error in your form. Please check the fields and try again.')
        else:
            get_name = Profile.objects.filter(email=request.user).values()
            form = JobForm()
            
            return render(request, 'admin_jobs_update.html', {'form': form,'name':get_name[0]['full_name']})  
    
    
    
     #@method_decorator(login_required, name='dispatch')  
    
    
    @action(detail=False, methods=['get'])
    def jobs(self, request):
      user = request.user 
      jobs = Jobs.objects.all().order_by('-date_posted') 
      base_domain = request.build_absolute_uri('/')
      
      is_jobs_page = True
       
        
      #This is what an admin will see
      if request.user.is_authenticated:
          
         print("Authenticated user: ", request.user)
         addBlog = True
          
         return render(request, 'job_list.html', {'jobs': jobs, 'addBlog': addBlog , 'base_domain':base_domain, 'is_jobs_page': is_jobs_page})
      
      #These are the users of the system.
      else:
          
        addBlog = False
          
        return render(request, 'job_list.html', {'jobs': jobs, 'base_domain': base_domain })
  
  
  
    #@method_decorator(login_required, name='dispatch')  
    
    @action(detail=False, methods=['get'], url_path=r'jobs/job-listing/(?P<job_reference_number>\d{5}-\d{10}-[A-Za-z])')
    #url_path=r'blog/(?P<job_reference_number>[-\w]+)'
    def singlejob(self, request, job_reference_number): 
        
        try:
            job = Jobs.objects.get(job_reference_number=job_reference_number)
            #blogs = Jobs.objects.all().order_by('-timestamp')[:4]
            #name_of_author = Profile.objects.filter(email=blog_post.author).values()
            
        except Jobs.DoesNotExist:
            
            raise Http404("Blog post not found")

        # Pass the blog post details to the template
        # Retrieve related jobs based on profession or job type (example filtering criteria)
        #related_jobs = Jobs.objects.filter(profession=job.profession).exclude(id=job.id)[:5]  # Example: limit to 5 related jobs
        
        # Prepare the context to pass to the template
        # Prepare the context to pass to the template
        context = {
            'job': job,
            'title': job.job_title,  # Job title to be used as the page title
            'salary': f"${job.salary:,.2f}",  # Formatting salary with commas and 2 decimal places
            'job_link': job.job_link,  # Link to the job application if available
        }
        
        # Render the blog post template with the context
        return render(request, 'single_job.html',context )

    
    #For the About Page
    @action(detail=False, methods=['get'])
    def about(self, request):
      user = request.user 
      return render(request, 'about.html',)
  
    #For the contact page
    @action(detail=False, methods=['get'])
    def contact(self, request):
      user = request.user 
      return render(request, 'contact.html',)
  
    #For the visa (Student) page
    @action(detail=False, methods=['get'])
    def visa(self, request):
      user = request.user 
      return render(request, 'visa.html',)
  
    #For the visa (business) page
    @action(detail=False, methods=['get'],  url_path=r'visa/business')
    def visa_business(self, request):
      user = request.user 
      return render(request, 'business-visa.html',)
  
    #For the visa (Work) page
    @action(detail=False, methods=['get'],  url_path=r'visa/work')
    def visa_work(self, request):
      user = request.user 
      return render(request, 'work-visa.html',)
  
    #For the visa (Family) page
    @action(detail=False, methods=['get'],  url_path=r'visa/family')
    def visa_family(self, request):
      user = request.user 
      return render(request, 'family-visa.html',)
  
    #For the visa (Transit) page
    @action(detail=False, methods=['get'],  url_path=r'visa/transit')
    def visa_transit(self, request):
      user = request.user 
      return render(request, 'transit-visa.html',)    
  
  
   #For the visa (Medical) page
    @action(detail=False, methods=['get'],  url_path=r'visa/medical')
    def visa_medical(self, request):
      user = request.user 
      return render(request, 'medical-visa.html',)
  
    
    @action(detail=False, methods=['get','post'])
    #@csrf_protect  # Ensure CSRF protection is enabled for this view   
    def send_email(self, request):
        if request.method == 'POST':  
            # Access CSRF token from cookies
            csrf_token = request.COOKIES.get('csrftoken')
            if csrf_token:
                print("CSRF token from cookies:", csrf_token)
            else:
                print("No CSRF token found in cookies.")

            try:
                # Parse the incoming JSON request body using DRF's request.data
                data = request.data  # DRF automatically parses the JSON body
                email = data.get('email')
                
                # Log the received email (can be useful for debugging)
                print("Received email:", email)

                # Validate the email address
                if not email or not re.match(r"[^@]+@[^@]+\.[^@]+", email):
                    return JsonResponse({'success': False, 'error': 'Invalid email address.'})

                # Prepare the HTML message for the first email
                html_message = render_to_string('email_template.html', {
                    'recipient_name': email,
                })

                # Send the first email to the dynamic email
                send_mail(
                    'VICTORIA VISA CONSULTANTS',  # Email subject
                    'Please view this email in HTML format',  # Text body (fallback for non-HTML clients)
                    settings.DEFAULT_FROM_EMAIL,  # Sender's email (configured in settings.py)
                    [email],  # Recipient's email
                    fail_silently=False,
                    html_message=html_message  # HTML message body
                )

                # Send the second email to the static email
                send_mail(
                    'VICTORIA VISA CONSULTANTS',  # Email subject
                    'Please view this email in HTML format',  # Text body (fallback for non-HTML clients)
                    settings.DEFAULT_FROM_EMAIL,  # Sender's email (configured in settings.py)
                    ["austinaustine4@gmail.com"],  # REMEMBER THIS SHOULD BE THE EMAIL FOR VICTORIA VISA
                    fail_silently=False,
                    html_message=f"""
                        <p>A user has interacted with the website. Below is their email address:</p>
                        <p><strong>{email}</strong></p>
                    """  # HTML message body with dynamic user email
                )

                # Return success response after both emails have been sent
                return JsonResponse({'success': True})

            except Exception as e:
                # Return error response
                return JsonResponse({'success': False, 'error': f'Error: {str(e)}'})

        # Return error if the method isn't POST
        else:       
            #return render(request, 'blog.html')
            return JsonResponse({'success': False, 'error': 'Invalid request method.'})

    
    #@method_decorator(login_required, name='dispatch')  
    @action(detail=False, methods=['get'])
    def delete(self, request):  
      print("To be deleted. ")  
      user = request.user 
      return render(request, 'delete.html')
  
  
  

