import re
import logging
from django.core.cache import cache
from django.conf import settings
from django.core.mail import send_mail
from django.http import HttpResponseForbidden
from .models import SuspiciousLog

logger = logging.getLogger(__name__)

class SuspiciousActivityMiddleware:
    EXEMPT_IPS = {"127.0.0.1", "::1"}  # IP yang dikecualikan (localhost & IPv6 loopback)

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        try:
            ip = self.get_client_ip(request)

            # ✅ Cek apakah Googlebot atau IP termasuk dalam daftar pengecualian
            if self.is_googlebot(request) or ip in self.EXEMPT_IPS:
                return self.get_response(request)  # Biarkan lewat tanpa blokir

            key = f"request_count_{ip}"
            request_count = cache.get(key, 0)

            # Cek apakah IP sudah diblokir sebelumnya
            suspicious_entry = SuspiciousLog.objects.filter(ip=ip).first()
            if suspicious_entry and suspicious_entry.blocked:
                logger.warning(f"🚨 Akses diblokir untuk IP: {ip}")
                return HttpResponseForbidden("🚨 Akses Diblokir: IP ini telah terdeteksi mencurigakan.")

            # Update request count di cache
            if request_count:
                cache.incr(key)
            else:
                cache.set(key, 1, timeout=60)  # Reset setiap 1 menit

            # Jika lebih dari 100 request dalam 1 menit, blokir & kirim email
            if request_count >= 70:
                self.send_alert_email(ip, request_count)
                SuspiciousLog.objects.update_or_create(
                    ip=ip,
                    defaults={"count": request_count, "blocked": True}
                )
                logger.warning(f"🚨 IP {ip} diblokir setelah {request_count} request dalam 1 menit.")
                return HttpResponseForbidden("🚨 Akses Diblokir: Terlalu banyak permintaan.")

            return self.get_response(request)

        except Exception as e:
            logger.exception("⚠️ Error in SuspiciousActivityMiddleware")
            return self.get_response(request)

    def get_client_ip(self, request):
        """Mendapatkan IP dari request dengan aman."""
        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 is_googlebot(self, request):
        """Deteksi apakah request berasal dari Googlebot berdasarkan User-Agent."""
        user_agent = request.META.get('HTTP_USER_AGENT', '').lower()
        return "googlebot" in user_agent

    def send_alert_email(self, ip, count):
        """Mengirim email peringatan jika ada aktivitas mencurigakan."""
        try:
            subject = "🚨 Peringatan: Aktivitas Mencurigakan Terdeteksi"
            message = f"Ada aktivitas mencurigakan dari IP: {ip} dengan {count} akses dalam 1 menit."
            recipient_list = ["adillrahmat21@gmail.com"]

            logger.info(f"📧 Mengirim email peringatan untuk IP {ip}")

            send_mail(
                subject,
                message,
                settings.DEFAULT_FROM_EMAIL,  # Gunakan email default Django
                recipient_list,
                fail_silently=False,
            )

            logger.info("✅ Email berhasil dikirim!")

        except Exception as e:
            logger.exception("⚠️ Gagal mengirim email peringatan")



import re
from django.http import HttpResponseForbidden
import logging

logger = logging.getLogger(__name__)

class BlockScraperMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        self.bot_patterns = [
            re.compile(r'bot', re.I),
            re.compile(r'scrapy', re.I),
            re.compile(r'crawl', re.I),
            re.compile(r'python-requests', re.I),
            re.compile(r'beautifulsoup', re.I),
            re.compile(r'curl', re.I),  # Pastikan curl tidak diblokir
            re.compile(r'wget', re.I),
            re.compile(r'spider', re.I),
            re.compile(r'selenium', re.I),
            re.compile(r'python-urllib', re.I),
            re.compile(r'java', re.I),
            re.compile(r'ruby', re.I),
            re.compile(r'php', re.I),
            re.compile(r'go-http-client', re.I),
            re.compile(r'node.js', re.I),
        ]
        self.excluded_agents = ["googlebot", "bingbot"]
        self.excluded_ips = ["127.0.0.1", "localhost"]

    def __call__(self, request):
        try:
            user_agent = request.META.get("HTTP_USER_AGENT", "").lower()
            client_ip = self.get_client_ip(request)

            # ✅ Jangan blokir jika IP dari localhost atau User-Agent dari bot yang diizinkan
            if client_ip in self.excluded_ips or any(bot in user_agent for bot in self.excluded_agents):
                logger.info(f"✅ Dikecualikan dari blokir: {client_ip} - {user_agent}")
                return self.get_response(request)

            # Logging untuk debugging
            logger.info(f"User-Agent: {user_agent}")

            if any(pattern.search(user_agent) for pattern in self.bot_patterns):
                logger.warning(f"❌ Bot terdeteksi dan diblokir: {user_agent}")
                return HttpResponseForbidden("Access Denied")

            return self.get_response(request)

        except Exception as e:
            logger.exception("⚠️ Error in BlockScraperMiddleware")
            return self.get_response(request)

    def get_client_ip(self, request):
        """Mendapatkan IP dari request dengan aman."""
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0].strip()
        else:
            ip = request.META.get('REMOTE_ADDR', '').strip()
        return ip



from django.core.cache import cache
from django.http import HttpResponseForbidden
import logging

logger = logging.getLogger(__name__)

class AntiSpamMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # Cek apakah request adalah POST dan path sesuai
        if request.method == 'POST' and (
            request.path.startswith('/subscribe/') or 
            request.path.startswith('/contact/') or 
            request.path.startswith('/contacts/')
        ):
            logger.info(f"Memeriksa spam untuk path: {request.path}")

            # Lewati pengecekan jika CAPTCHA sudah lolos
            if request.session.get('recaptcha_passed', False):
                logger.info("CAPTCHA sudah lolos, melewati pengecekan spam.")
                return self.get_response(request)

            # Ambil IP dan email dari request
            ip = request.META.get('REMOTE_ADDR')
            email = request.POST.get('email', '').strip().lower()  # Normalisasi email

            # Buat key cache untuk IP dan email
            ip_cache_key = f"form_submission_ip_{ip}"
            email_cache_key = f"form_submission_email_{email}"

            # Ambil jumlah pengiriman dari cache
            ip_submission_count = cache.get(ip_cache_key, 0)
            email_submission_count = cache.get(email_cache_key, 0)

            logger.info(f"IP: {ip}, Jumlah Pengiriman: {ip_submission_count}")
            logger.info(f"Email: {email}, Jumlah Pengiriman: {email_submission_count}")

            # Blokir jika lebih dari 3 kali pengiriman dari IP atau email yang sama
            if ip_submission_count >= 3 or email_submission_count >= 3:
                logger.warning(f"🚨 Spam terdeteksi! IP: {ip}, Email: {email}")
                return HttpResponseForbidden("Anda telah mencapai batas pengiriman form.")

            # Tingkatkan jumlah pengiriman dan simpan ke cache
            cache.set(ip_cache_key, ip_submission_count + 1, 36)  # Simpan selama 1 jam
            cache.set(email_cache_key, email_submission_count + 1, 36)  # Simpan selama 1 jam

        return self.get_response(request)
