"""Structured error handling for the mesh system."""
from __future__ import annotations

from typing import Any, Dict, Optional

from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse


class MeshError(Exception):
    """Base mesh exception with structured error info."""

    def __init__(self, code: str, message: str, details: Optional[Dict[str, Any]] = None,
                 status_code: int = 500):
        self.code = code
        self.message = message
        self.details = details or {}
        self.status_code = status_code
        super().__init__(message)

    def to_dict(self) -> dict:
        return {
            "error": {
                "code": self.code,
                "message": self.message,
                "details": self.details,
            }
        }


class NodeNotFoundError(MeshError):
    def __init__(self, node_id: str):
        super().__init__(
            code="NODE_NOT_FOUND",
            message=f"Node {node_id} not found",
            details={"node_id": node_id},
            status_code=404,
        )


class AuthenticationError(MeshError):
    def __init__(self, message: str = "Authentication failed"):
        super().__init__(
            code="AUTH_FAILED",
            message=message,
            status_code=401,
        )


class ValidationError(MeshError):
    def __init__(self, message: str, details: Optional[Dict[str, Any]] = None):
        super().__init__(
            code="VALIDATION_ERROR",
            message=message,
            details=details or {},
            status_code=422,
        )


def install_error_handlers(app: FastAPI, production: bool = True) -> None:
    """Register structured error handlers on a FastAPI app.

    In production mode, error details are sanitized to prevent information leakage.
    """
    import logging
    _logger = logging.getLogger(__name__)

    @app.exception_handler(MeshError)
    async def mesh_error_handler(request: Request, exc: MeshError) -> JSONResponse:
        return JSONResponse(
            status_code=exc.status_code,
            content=exc.to_dict(),
        )

    @app.exception_handler(Exception)
    async def generic_error_handler(request: Request, exc: Exception) -> JSONResponse:
        """Catch-all handler that sanitizes unexpected errors in production."""
        from mesh.security.validation import ErrorSanitizer
        _logger.error("Unhandled exception on %s %s: %s",
                       request.method, request.url.path, exc, exc_info=True)
        message = ErrorSanitizer.safe_error_response(exc, production=production)
        return JSONResponse(
            status_code=500,
            content={
                "error": {
                    "code": "INTERNAL_ERROR",
                    "message": message,
                    "details": {},
                }
            },
        )
