"""
Error Handler Middleware

This middleware handles exceptions globally.
"""
import traceback
import logging
from typing import Callable

from fastapi import Request, Response, status
from fastapi.responses import JSONResponse
from starlette.middleware.base import BaseHTTPMiddleware

from api.middleware.correlation import get_correlation_id


logger = logging.getLogger(__name__)


class ErrorHandlerMiddleware(BaseHTTPMiddleware):
    """Middleware for global error handling."""
    
    async def dispatch(
        self, request: Request, call_next: Callable[[Request], Response]
    ) -> Response:
        """
        Process request and handle errors.
        
        Args:
            request: The incoming request
            call_next: The next middleware/handler
            
        Returns:
            The response or error response
        """
        try:
            response = await call_next(request)
            return response
        except Exception as exc:
            correlation_id = get_correlation_id()
            
            # Log the error
            logger.error(
                "Unhandled exception occurred",
                extra={
                    "correlation_id": correlation_id,
                    "method": request.method,
                    "url": str(request.url),
                    "error": str(exc),
                    "traceback": traceback.format_exc(),
                }
            )
            
            # Return appropriate error response
            if isinstance(exc, ValueError):
                return JSONResponse(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    content={
                        "error": {
                            "type": "VALIDATION_ERROR",
                            "message": str(exc),
                            "correlation_id": correlation_id,
                        }
                    }
                )
            
            # Generic internal server error
            return JSONResponse(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                content={
                    "error": {
                        "type": "INTERNAL_ERROR",
                        "message": "An internal server error occurred",
                        "correlation_id": correlation_id,
                    }
                }
            )