"""
Exception handling for AI Service.
[AC-AISVC-03, AC-AISVC-04, AC-AISVC-05] Structured error responses.
"""

from fastapi import HTTPException, Request, status
from fastapi.responses import JSONResponse

from app.models import ErrorCode, ErrorResponse


class AIServiceException(Exception):
    def __init__(
        self,
        code: ErrorCode,
        message: str,
        status_code: int = status.HTTP_500_INTERNAL_SERVER_ERROR,
        details: list[dict] | None = None,
    ):
        self.code = code
        self.message = message
        self.status_code = status_code
        self.details = details
        super().__init__(message)


class MissingTenantIdException(AIServiceException):
    def __init__(self, message: str = "Missing required header: X-Tenant-Id"):
        super().__init__(
            code=ErrorCode.MISSING_TENANT_ID,
            message=message,
            status_code=status.HTTP_400_BAD_REQUEST,
        )


class InvalidRequestException(AIServiceException):
    def __init__(self, message: str, details: list[dict] | None = None):
        super().__init__(
            code=ErrorCode.INVALID_REQUEST,
            message=message,
            status_code=status.HTTP_400_BAD_REQUEST,
            details=details,
        )


class ServiceUnavailableException(AIServiceException):
    def __init__(self, message: str = "Service temporarily unavailable"):
        super().__init__(
            code=ErrorCode.SERVICE_UNAVAILABLE,
            message=message,
            status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
        )


class TimeoutException(AIServiceException):
    def __init__(self, message: str = "Request timeout"):
        super().__init__(
            code=ErrorCode.TIMEOUT,
            message=message,
            status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
        )


async def ai_service_exception_handler(request: Request, exc: AIServiceException) -> JSONResponse:
    return JSONResponse(
        status_code=exc.status_code,
        content=ErrorResponse(
            code=exc.code.value,
            message=exc.message,
            details=exc.details,
        ).model_dump(exclude_none=True),
    )


async def http_exception_handler(request: Request, exc: HTTPException) -> JSONResponse:
    if exc.status_code == status.HTTP_400_BAD_REQUEST:
        code = ErrorCode.INVALID_REQUEST
    elif exc.status_code == status.HTTP_503_SERVICE_UNAVAILABLE:
        code = ErrorCode.SERVICE_UNAVAILABLE
    else:
        code = ErrorCode.INTERNAL_ERROR

    return JSONResponse(
        status_code=exc.status_code,
        content=ErrorResponse(
            code=code.value,
            message=exc.detail or "An error occurred",
        ).model_dump(exclude_none=True),
    )


async def generic_exception_handler(request: Request, exc: Exception) -> JSONResponse:
    import logging
    logger = logging.getLogger(__name__)
    logger.error(f"Unhandled exception: {type(exc).__name__}: {exc}", exc_info=True)
    return JSONResponse(
        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
        content=ErrorResponse(
            code=ErrorCode.INTERNAL_ERROR.value,
            message="An unexpected error occurred",
        ).model_dump(exclude_none=True),
    )
