# -*- coding: utf-8 -*-
"""
Authentification App Signals

This module contains signal handlers for authentication-related events.
"""

from django.db.models.signals import post_save
from django.contrib.auth.signals import user_logged_in, user_logged_out, user_login_failed
from django.dispatch import receiver
from django.contrib.auth import get_user_model
from django.utils import timezone
from .models import LoginAttempt
import logging

User = get_user_model()
logger = logging.getLogger(__name__)


@receiver(user_logged_in)
def log_successful_login(sender, request, user, **kwargs):
    """
    Log successful login attempts.
    """
    ip_address = get_client_ip(request)
    user_agent = request.META.get('HTTP_USER_AGENT', '')
    
    LoginAttempt.objects.create(
        username=user.username,
        ip_address=ip_address,
        user_agent=user_agent,
        success=True
    )
    
    logger.info(f"Successful login for user {user.username} from {ip_address}")


@receiver(user_login_failed)
def log_failed_login(sender, credentials, request, **kwargs):
    """
    Log failed login attempts.
    """
    username = credentials.get('username', 'unknown')
    ip_address = get_client_ip(request)
    user_agent = request.META.get('HTTP_USER_AGENT', '')
    
    LoginAttempt.objects.create(
        username=username,
        ip_address=ip_address,
        user_agent=user_agent,
        success=False,
        failure_reason='Invalid credentials'
    )
    
    logger.warning(f"Failed login attempt for username {username} from {ip_address}")


@receiver(user_logged_out)
def log_user_logout(sender, request, user, **kwargs):
    """
    Log user logout events.
    """
    if user:
        ip_address = get_client_ip(request)
        logger.info(f"User {user.username} logged out from {ip_address}")


@receiver(post_save, sender=User)
def user_post_save(sender, instance, created, **kwargs):
    """
    Handle user creation and updates.
    """
    if created:
        logger.info(f"New user created: {instance.username}")
        
        # Send welcome email or perform other actions
        # This can be extended based on requirements
        
    else:
        logger.info(f"User updated: {instance.username}")


def get_client_ip(request):
    """
    Get the client IP address from the 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


@receiver(post_save, sender=LoginAttempt)
def check_suspicious_activity(sender, instance, created, **kwargs):
    """
    Check for suspicious login activity and take action if needed.
    """
    if created and not instance.success:
        # Check for multiple failed attempts from same IP
        recent_failures = LoginAttempt.objects.filter(
            ip_address=instance.ip_address,
            success=False,
            timestamp__gte=timezone.now() - timezone.timedelta(minutes=15)
        ).count()
        
        if recent_failures >= 5:
            logger.warning(
                f"Suspicious activity detected: {recent_failures} failed login attempts "
                f"from IP {instance.ip_address} in the last 15 minutes"
            )
            
            # Here you could implement additional security measures:
            # - Send alert emails
            # - Temporarily block the IP
            # - Trigger additional security checks
            
        # Check for multiple failed attempts for same username
        username_failures = LoginAttempt.objects.filter(
            username=instance.username,
            success=False,
            timestamp__gte=timezone.now() - timezone.timedelta(hours=1)
        ).count()
        
        if username_failures >= 3:
            logger.warning(
                f"Multiple failed login attempts for username {instance.username}: "
                f"{username_failures} attempts in the last hour"
            )