"""
Centralized error handling utilities.

This module provides standardized error handling for views across the application,
ensuring consistent logging, user messages, and API responses.
"""

import logging
from typing import Any

from django.contrib import messages
from django.http import HttpRequest
from rest_framework import status
from rest_framework.response import Response

from apps.core.exceptions import ThrillWikiException

logger = logging.getLogger(__name__)


class ErrorHandler:
    """Centralized error handling for views."""

    @staticmethod
    def handle_view_error(
        request: HttpRequest,
        error: Exception,
        user_message: str = "An error occurred",
        log_message: str | None = None,
        level: str = "error",
    ) -> None:
        """
        Handle errors in template views.

        Logs the error with appropriate context and displays a user-friendly
        message using Django's messages framework.

        Args:
            request: HTTP request object
            error: Exception that occurred
            user_message: Message to show to the user (should be user-friendly)
            log_message: Message to log (defaults to str(error) with user_message prefix)
            level: Log level - one of "error", "warning", "info"

        Example:
            try:
                ParkService.create_park(...)
            except ServiceError as e:
                ErrorHandler.handle_view_error(
                    request,
                    e,
                    user_message="Failed to create park",
                    log_message=f"Park creation failed for user {request.user.id}"
                )
        """
        log_msg = log_message or f"{user_message}: {str(error)}"

        if level == "error":
            logger.error(log_msg, exc_info=True)
        elif level == "warning":
            logger.warning(log_msg)
        else:
            logger.info(log_msg)

        messages.error(request, user_message)

    @staticmethod
    def handle_api_error(
        error: Exception,
        user_message: str = "An error occurred",
        log_message: str | None = None,
        status_code: int = status.HTTP_400_BAD_REQUEST,
    ) -> Response:
        """
        Handle errors in API views.

        Logs the error and returns a standardized DRF Response with error details.

        Args:
            error: Exception that occurred
            user_message: Message to return to the client (should be user-friendly)
            log_message: Message to log (defaults to str(error) with user_message prefix)
            status_code: HTTP status code to return

        Returns:
            DRF Response with error details in standard format

        Example:
            try:
                result = ParkService.create_park(...)
            except ServiceError as e:
                return ErrorHandler.handle_api_error(
                    e,
                    user_message="Failed to create park photo",
                    status_code=status.HTTP_400_BAD_REQUEST
                )
        """
        log_msg = log_message or f"{user_message}: {str(error)}"
        logger.error(log_msg, exc_info=True)

        # Build error response
        error_data: dict[str, Any] = {
            "error": user_message,
            "detail": str(error),
        }

        # Include additional details for ThrillWikiException subclasses
        if isinstance(error, ThrillWikiException):
            error_data["error_code"] = error.error_code
            if error.details:
                error_data["details"] = error.details

        return Response(error_data, status=status_code)

    @staticmethod
    def handle_success(
        request: HttpRequest,
        message: str,
        level: str = "success",
    ) -> None:
        """
        Handle success messages in template views.

        Args:
            request: HTTP request object
            message: Success message to display
            level: Message level - one of "success", "info", "warning"
        """
        if level == "success":
            messages.success(request, message)
        elif level == "info":
            messages.info(request, message)
        elif level == "warning":
            messages.warning(request, message)

    @staticmethod
    def api_success_response(
        data: Any = None,
        message: str = "Success",
        status_code: int = status.HTTP_200_OK,
    ) -> Response:
        """
        Create a standardized success response for API views.

        Args:
            data: Response data (optional)
            message: Success message
            status_code: HTTP status code

        Returns:
            DRF Response with success data in standard format
        """
        response_data: dict[str, Any] = {
            "status": "success",
            "message": message,
        }

        if data is not None:
            response_data["data"] = data

        return Response(response_data, status=status_code)
