"""
Vues personnalisées pour gérer les erreurs HTTP
"""

from django.shortcuts import render
from django.http import HttpResponseNotFound, HttpResponseServerError, HttpResponseForbidden
from django.views.decorators.csrf import requires_csrf_token
from django.views.decorators.cache import never_cache
import logging

logger = logging.getLogger('django')


@never_cache
@requires_csrf_token
def error_404(request, exception=None):
    """
    Vue personnalisée pour l'erreur 404 (Page non trouvée)
    """
    logger.warning(f"Erreur 404 pour l'URL : {request.path} - User: {request.user}")

    context = {
        'error_code': 404,
        'request_path': request.path,
        'user': request.user,
        'exception': str(exception) if exception else None,
    }

    try:
        return render(request, 'errors/404.html', context, status=404)
    except Exception as e:
        logger.error(f"Erreur lors du rendu de la page 404 : {e}")
        return HttpResponseNotFound(
            '<h1>Page non trouvée</h1><p>La page demandée n\'existe pas.</p>'
        )


@never_cache
@requires_csrf_token
def error_500(request):
    """
    Vue personnalisée pour l'erreur 500 (Erreur serveur)
    """
    logger.error(f"Erreur 500 pour l'URL : {request.path} - User: {request.user}")

    context = {
        'error_code': 500,
        'request_path': request.path,
        'user': request.user,
    }

    try:
        return render(request, 'errors/500.html', context, status=500)
    except Exception as e:
        logger.critical(f"Erreur critique lors du rendu de la page 500 : {e}")
        return HttpResponseServerError(
            '<h1>Erreur serveur</h1><p>Une erreur interne est survenue.</p>'
        )


@never_cache
@requires_csrf_token
def error_403(request, exception=None):
    """
    Vue personnalisée pour l'erreur 403 (Accès interdit)
    """
    logger.warning(f"Erreur 403 pour l'URL : {request.path} - User: {request.user}")

    context = {
        'error_code': 403,
        'request_path': request.path,
        'user': request.user,
        'exception': str(exception) if exception else None,
    }

    try:
        return render(request, 'errors/403.html', context, status=403)
    except Exception as e:
        logger.error(f"Erreur lors du rendu de la page 403 : {e}")
        return HttpResponseForbidden(
            '<h1>Accès interdit</h1><p>Vous n\'avez pas l\'autorisation d\'accéder à cette ressource.</p>'
        )


@never_cache
def error_405(request, exception=None):
    """
    Vue personnalisée pour l'erreur 405 (Méthode non autorisée)
    """
    logger.warning(f"Erreur 405 pour l'URL : {request.path} - Méthode: {request.method} - User: {request.user}")

    context = {
        'error_code': 405,
        'request_path': request.path,
        'request_method': request.method,
        'user': request.user,
        'exception': str(exception) if exception else None,
    }

    try:
        return render(request, 'errors/405.html', context, status=405)
    except Exception as e:
        logger.error(f"Erreur lors du rendu de la page 405 : {e}")
        return render(request, 'errors/base_error.html', {
            'error_code': 405,
            'error_message': 'Méthode non autorisée'
        }, status=405)


@never_cache
def error_503(request, exception=None):
    """
    Vue personnalisée pour l'erreur 503 (Service indisponible)
    """
    logger.warning(f"Erreur 503 pour l'URL : {request.path} - User: {request.user}")

    context = {
        'error_code': 503,
        'request_path': request.path,
        'user': request.user,
        'exception': str(exception) if exception else None,
    }

    try:
        return render(request, 'errors/503.html', context, status=503)
    except Exception as e:
        logger.error(f"Erreur lors du rendu de la page 503 : {e}")
        return render(request, 'errors/base_error.html', {
            'error_code': 503,
            'error_message': 'Service temporairement indisponible'
        }, status=503)


@never_cache
def error_400(request, exception=None):
    """
    Vue personnalisée pour l'erreur 400 (Mauvaise requête)
    """
    logger.warning(f"Erreur 400 pour l'URL : {request.path} - User: {request.user}")

    context = {
        'error_code': 400,
        'request_path': request.path,
        'user': request.user,
        'exception': str(exception) if exception else None,
        'error_title': 'Requête incorrecte',
        'error_description': 'La requête envoyée au serveur est malformée ou incomplète.',
        'suggestions': [
            'Vérifiez les données saisies dans le formulaire',
            'Assurez-vous que tous les champs requis sont remplis',
            'Contactez le support technique si le problème persiste'
        ]
    }

    try:
        return render(request, 'errors/base_error.html', context, status=400)
    except Exception as e:
        logger.error(f"Erreur lors du rendu de la page 400 : {e}")
        return render(request, 'errors/base_error.html', {
            'error_code': 400,
            'error_message': 'Requête incorrecte'
        }, status=400)


class DatabaseErrorHandler:
    """
    Gestionnaire spécialisé pour les erreurs de base de données
    """

    @staticmethod
    def handle_mysql_gone_away(request, error):
        """
        Gérer spécifiquement l'erreur MySQL "server has gone away"
        """
        logger.error(f"MySQL Gone Away - URL: {request.path} - Error: {error}")

        context = {
            'error_code': 503,
            'error_title': 'Problème de connexion à la base de données',
            'error_description': 'Nous rencontrons actuellement des difficultés de connexion à notre base de données.',
            'technical_details': str(error),
            'suggestions': [
                'Cette erreur est généralement temporaire',
                'Veuillez patienter quelques instants et réessayer',
                'Nos équipes techniques ont été automatiquement alertées'
            ],
            'auto_refresh': True,
            'refresh_time': 30
        }

        return render(request, 'errors/503.html', context, status=503)

    @staticmethod
    def handle_database_error(request, error):
        """
        Gérer les erreurs générales de base de données
        """
        logger.error(f"Database Error - URL: {request.path} - Error: {error}")

        context = {
            'error_code': 500,
            'error_title': 'Erreur de base de données',
            'error_description': 'Un problème est survenu lors de l\'accès aux données.',
            'technical_details': str(error),
            'suggestions': [
                'Réessayez dans quelques instants',
                'Vérifiez votre connexion internet',
                'Contactez le support si le problème persiste'
            ]
        }

        return render(request, 'errors/500.html', context, status=500)