"""Domain error → HTTP response mapping.

This module provides a single exception handler that converts
domain-layer errors into structured JSON responses, keeping
the service layer free from FastAPI's ``HTTPException``.
"""

# Import Request from fastapi
from fastapi import Request

# Import JSONResponse from fastapi.responses
from fastapi.responses import JSONResponse

# Import  from app.domain.errors
from app.domain.errors import (
    BusinessRuleViolation,
    DomainError,
    DuplicateEntityError,
    EntityNotFoundError,
    InvalidOperationError,
    InvalidStateTransition,
    PermissionViolation,
)

# Assign EXCEPTION_STATUS_MAP = {
EXCEPTION_STATUS_MAP: dict[type[DomainError], int] = {
    # Entry: EntityNotFoundError
    EntityNotFoundError: 404,
    # Entry: DuplicateEntityError
    DuplicateEntityError: 409,
    # Entry: InvalidStateTransition
    InvalidStateTransition: 400,
    # Entry: InvalidOperationError
    InvalidOperationError: 400,
    # Entry: BusinessRuleViolation
    BusinessRuleViolation: 400,
    # Entry: PermissionViolation
    PermissionViolation: 403,
}


# Define async function domain_exception_handler
async def domain_exception_handler(
    # Entry: request
    request: Request,
    # Entry: exc
    exc: DomainError,
) -> JSONResponse:
    """Convert a :class:`DomainError` into a JSON error response."""
    # Assign status_code = EXCEPTION_STATUS_MAP.get(type(exc), 400)
    status_code = EXCEPTION_STATUS_MAP.get(type(exc), 400)

    # Assign content = {"detail": exc.message, "code": exc.code}
    content: dict = {"detail": exc.message, "code": exc.code}

    # Check: isinstance(exc, InvalidStateTransition)
    if isinstance(exc, InvalidStateTransition):
        # Assign content["current_state"] = exc.current_state
        content["current_state"] = exc.current_state
        # Assign content["target_state"] = exc.target_state
        content["target_state"] = exc.target_state
        # Assign content["valid_transitions"] = exc.valid_transitions
        content["valid_transitions"] = exc.valid_transitions

    # Return JSONResponse(status_code=status_code, content=content)
    return JSONResponse(status_code=status_code, content=content)
