"""
Error translation utilities
Maps gRPC errors to HTTP status codes and user-friendly messages
"""
from typing import Tuple, Any
import grpc
from fastapi import status

def grpc_to_http_status(grpc_code: grpc.StatusCode) -> int:
    """
    Map gRPC status code to HTTP status code

    Args:
        grpc_code: gRPC status code

    Returns:
        HTTP status code integer
    """
    mapping = {
        grpc.StatusCode.OK: status.HTTP_200_OK,
        grpc.StatusCode.INVALID_ARGUMENT: status.HTTP_400_BAD_REQUEST,
        grpc.StatusCode.NOT_FOUND: status.HTTP_404_NOT_FOUND,
        grpc.StatusCode.ALREADY_EXISTS: status.HTTP_409_CONFLICT,
        grpc.StatusCode.PERMISSION_DENIED: status.HTTP_403_FORBIDDEN,
        grpc.StatusCode.UNAUTHENTICATED: status.HTTP_401_UNAUTHORIZED,
        grpc.StatusCode.RESOURCE_EXHAUSTED: status.HTTP_429_TOO_MANY_REQUESTS,
        grpc.StatusCode.FAILED_PRECONDITION: status.HTTP_412_PRECONDITION_FAILED,
        grpc.StatusCode.ABORTED: status.HTTP_409_CONFLICT,
        grpc.StatusCode.OUT_OF_RANGE: status.HTTP_400_BAD_REQUEST,
        grpc.StatusCode.UNIMPLEMENTED: status.HTTP_501_NOT_IMPLEMENTED,
        grpc.StatusCode.INTERNAL: status.HTTP_500_INTERNAL_SERVER_ERROR,
        grpc.StatusCode.UNAVAILABLE: status.HTTP_503_SERVICE_UNAVAILABLE,
        grpc.StatusCode.DATA_LOSS: status.HTTP_500_INTERNAL_SERVER_ERROR,
        grpc.StatusCode.DEADLINE_EXCEEDED: status.HTTP_504_GATEWAY_TIMEOUT,
        grpc.StatusCode.CANCELLED: status.HTTP_499_CLIENT_CLOSED_REQUEST,
        grpc.StatusCode.UNKNOWN: status.HTTP_500_INTERNAL_SERVER_ERROR,
    }

    return mapping.get(grpc_code, status.HTTP_500_INTERNAL_SERVER_ERROR)

def grpc_error_to_http(error: grpc.RpcError) -> Tuple[int, dict]:
    """
    Convert gRPC error to HTTP status code and response body

    Args:
        error: gRPC RpcError

    Returns:
        Tuple of (status_code, response_dict)
    """
    grpc_code = error.code()
    grpc_details = error.details()

    http_status = grpc_to_http_status(grpc_code)

    response = {
        "error": grpc_code.name,
        "message": grpc_details or "An error occurred",
        "grpc_code": grpc_code.value[0]  # Numeric gRPC code
    }

    return http_status, response

def create_error_response(
    error_type: str,
    message: str,
    status_code: int = status.HTTP_500_INTERNAL_SERVER_ERROR,
    details: dict = None
) -> Tuple[int, dict]:
    """
    Create standardized error response

    Args:
        error_type: Error type/category
        message: Human-readable error message
        status_code: HTTP status code
        details: Optional additional details

    Returns:
        Tuple of (status_code, response_dict)
    """
    response = {
        "error": error_type,
        "message": message
    }

    if details:
        response["details"] = details

    return status_code, response

# Common error responses
def not_found_error(resource: str, resource_id: Any) -> Tuple[int, dict]:
    """Create 404 not found error"""
    return create_error_response(
        "NotFound",
        f"{resource} with ID {resource_id} not found",
        status.HTTP_404_NOT_FOUND
    )

def validation_error(message: str, details: dict = None) -> Tuple[int, dict]:
    """Create 400 validation error"""
    return create_error_response(
        "ValidationError",
        message,
        status.HTTP_400_BAD_REQUEST,
        details
    )

def unauthorized_error(message: str = "Authentication required") -> Tuple[int, dict]:
    """Create 401 unauthorized error"""
    return create_error_response(
        "Unauthorized",
        message,
        status.HTTP_401_UNAUTHORIZED
    )

def forbidden_error(message: str = "Permission denied") -> Tuple[int, dict]:
    """Create 403 forbidden error"""
    return create_error_response(
        "Forbidden",
        message,
        status.HTTP_403_FORBIDDEN
    )

def internal_error(message: str = "Internal server error") -> Tuple[int, dict]:
    """Create 500 internal error"""
    return create_error_response(
        "InternalError",
        message,
        status.HTTP_500_INTERNAL_SERVER_ERROR
    )

def service_unavailable_error(service: str) -> Tuple[int, dict]:
    """Create 503 service unavailable error"""
    return create_error_response(
        "ServiceUnavailable",
        f"{service} is currently unavailable",
        status.HTTP_503_SERVICE_UNAVAILABLE
    )
