"""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``.
"""

from fastapi import Request
from fastapi.responses import JSONResponse

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

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


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

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

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

    return JSONResponse(status_code=status_code, content=content)
