from django.http import JsonResponse
from django.shortcuts import render, redirect
from django.views.generic import TemplateView
from .models import Profile, Company, Skill, Project, Education, Service, Testimonial, Brand, ContactMessage
from django.contrib import messages
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
from django.utils.html import strip_tags
from django.conf import settings
from django.templatetags.static import static
import requests
import time
from django.utils import timezone
from .models import Profile, Company, Skill, Project, Education, Service, Testimonial, Brand, ContactMessage, IPRateLimit

def get_client_ip(request):
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
    if x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip

def verify_turnstile(token, ip, expected_action=None, expected_hostname=None):
    secret_key = getattr(settings, 'TURNSTILE_SECRET_KEY', None)
    if not secret_key:
        return True # Skip if not configured
    
    try:
        response = requests.post(
            'https://challenges.cloudflare.com/turnstile/v0/siteverify',
            data={
                'secret': secret_key,
                'response': token,
                'remoteip': ip
            },
            timeout=5
        )
        result = response.json()
        
        if not result.get('success'):
            return False
            
        # Validate action to prevent token reuse across different forms
        if expected_action and result.get('action') != expected_action:
            return False
            
        # Validate hostname to prevent tokens from other sites being used
        if expected_hostname and result.get('hostname') != expected_hostname:
            return False
            
        return True
    except Exception:
        return False

class HomeView(TemplateView):
    template_name = "home.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['profile'] = Profile.objects.first()
        context['companies'] = Company.objects.all()
        context['skills'] = Skill.objects.all()
        context['projects'] = Project.objects.all()
        context['education'] = Education.objects.all()
        context['services'] = Service.objects.all().order_by('order')
        context['testimonials'] = Testimonial.objects.all()
        context['brands'] = Brand.objects.all()
        return context

def contact_submit(request):
    if request.method == "POST":
        # 1. Honeypot check (hidden field)
        honeypot = request.POST.get('website_url_check')
        if honeypot:
            # Bot filled the honeypot
            return JsonResponse({'status': 'error', 'message': 'Bot detected.'}, status=400)

        # 2. Time-based check (minimum 3 seconds to fill form)
        form_load_time = request.POST.get('load_time')
        if form_load_time:
            try:
                elapsed = time.time() - float(form_load_time)
                if elapsed < 3:
                    return JsonResponse({'status': 'error', 'message': 'Please take your time to fill the form.'}, status=400)
            except (ValueError, TypeError):
                pass

        # 3. IP Rate Limiting
        client_ip = get_client_ip(request)
        rate_limit, created = IPRateLimit.objects.get_or_create(ip_address=client_ip)
        
        # Reset count if it's a new day
        if rate_limit.last_reset.date() < timezone.now().date():
            rate_limit.count = 0
            rate_limit.last_reset = timezone.now()
        
        MAX_DAILY_MESSAGES = getattr(settings, 'CONTACT_FORM_DAILY_LIMIT', 5)
        if rate_limit.count >= MAX_DAILY_MESSAGES:
            return JsonResponse({
                'status': 'error', 
                'message': f'Daily limit reached for this IP. Max {MAX_DAILY_MESSAGES} messages per day.'
            }, status=429)

        # 4. Turnstile Verification
        turnstile_token = request.POST.get('cf-turnstile-response')
        if not verify_turnstile(turnstile_token, client_ip, expected_action='contact_form', expected_hostname=request.get_host()):
            return JsonResponse({'status': 'error', 'message': 'Security verification failed.'}, status=400)

        name = request.POST.get('name')
        email = request.POST.get('email')
        phone = request.POST.get('phone')
        subject = request.POST.get('subject')
        message = request.POST.get('message')
        
        # Validation
        if not name or not email or not phone or not subject or not message:
            if request.headers.get('x-requested-with') == 'XMLHttpRequest':
                return JsonResponse({'status': 'error', 'message': 'All fields are mandatory.'}, status=400)
            messages.error(request, "All fields are mandatory.")
            return redirect('home')

        # Save to database
        ContactMessage.objects.create(
            name=name,
            email=email,
            phone=phone,
            subject=subject,
            message=message,
            ip_address=client_ip
        )

        # Increment rate limit count
        rate_limit.count += 1
        rate_limit.save()

        # Get profile for image and details
        profile = Profile.objects.first()
        profile_img_url = request.build_absolute_uri(static('images/sadman-sakib-jisan-hero.png'))
        
        # Prepare context for emails
        context = {
            'name': name,
            'email': email,
            'phone': phone,
            'subject': subject,
            'message': message,
            'profile': profile,
            'profile_img_url': profile_img_url,
        }

        # Send Email to Admin (Jisan)
        try:
            admin_html_content = render_to_string('emails/admin_notification.html', context)
            admin_text_content = strip_tags(admin_html_content)
            
            from_name = "CEO | Sadman Sakib Jisan"
            from_email_formatted = f"{from_name} <{settings.DEFAULT_FROM_EMAIL}>"

            admin_email = EmailMultiAlternatives(
                subject=f"New Portfolio Inquiry: {subject}",
                body=admin_text_content,
                from_email=from_email_formatted,
                to=[settings.ADMIN_EMAIL],
            )
            admin_email.attach_alternative(admin_html_content, "text/html")
            admin_email.send()

            # Send Confirmation Email to Client
            client_html_content = render_to_string('emails/client_confirmation.html', context)
            client_text_content = strip_tags(client_html_content)
            
            client_email = EmailMultiAlternatives(
                subject="Technical Inquiry Received | S. S. Jisan",
                body=client_text_content,
                from_email=from_email_formatted,
                to=[email],
            )
            client_email.attach_alternative(client_html_content, "text/html")
            client_email.send()
        except Exception as e:
            # Fallback for logging if needed
            print(f"Mail delivery failed: {str(e)}")
            if request.headers.get('x-requested-with') == 'XMLHttpRequest':
                return JsonResponse({
                    'status': 'error', 
                    'message': 'Mail delivery failed. Please try again later or contact directly via WhatsApp.'
                }, status=500)
            messages.error(request, f"Error sending email. Please try again.")
            return redirect('home')

        if request.headers.get('x-requested-with') == 'XMLHttpRequest':
            return JsonResponse({'status': 'success', 'message': 'Transmission Successful'})
        
        messages.success(request, "Transmission Successful")
        return redirect('home')
    return redirect('home')
