"""{{ Name }} views with routes and business logic."""

from pydantic import Field
from robyn import Request, Response as RobynResponse, Robyn

from ..models import {{ Name }}Repository, transaction
from ..schemas import (
    PrimaryKey,
    PublicEntity,
    Response,
    ResponseMulti,
    parse_primary_key,
)
from ..utils import JSON_HEADERS


class {{ Name }}CreateBody(PublicEntity):
    """Request body for creating a {{ name }}."""

    name: str = Field(
        description="{{ Name }} name",
        min_length=1,
        max_length=255,
    )
    # Add your fields here


class {{ Name }}UpdateBody(PublicEntity):
    """Request body for updating a {{ name }}."""

    name: str | None = Field(
        default=None,
        description="{{ Name }} name",
        min_length=1,
        max_length=255,
    )
    # Add your fields here


class {{ Name }}Public(PublicEntity):
    """Public {{ name }} response model."""

    id: PrimaryKey = Field(description="{{ Name }} ID")
    name: str = Field(description="{{ Name }} name")
    # Add your fields here


def register(app: Robyn) -> None:
    """Register {{ name }} routes."""

    @app.get("/{{ name }}s", openapi_name="List {{ Name }}s", openapi_tags=["{{ Name }}"])
    async def {{ name }}_list(request: Request) -> ResponseMulti[{{ Name }}Public]:
        """Get all {{ name }}s."""
        async with transaction():
            repo = {{ Name }}Repository()
            items = [item async for item in repo.all()]
        return ResponseMulti[{{ Name }}Public](
            result=[{{ Name }}Public.model_validate(item) for item in items]
        )

    @app.get("/{{ name }}s/:id", openapi_name="Get {{ Name }}", openapi_tags=["{{ Name }}"])
    async def {{ name }}_get(request: Request) -> Response[{{ Name }}Public]:
        """Get a {{ name }} by ID."""
        id_ = parse_primary_key(request.path_params["id"])
        async with transaction():
            repo = {{ Name }}Repository()
            item = await repo.get(id_=id_)
        return Response[{{ Name }}Public](result={{ Name }}Public.model_validate(item))

    @app.post("/{{ name }}s", openapi_name="Create {{ Name }}", openapi_tags=["{{ Name }}"])
    async def {{ name }}_create(body: {{ Name }}CreateBody) -> RobynResponse:
        """Create a new {{ name }}."""
        async with transaction():
            repo = {{ Name }}Repository()
            item = await repo.create(body.model_dump())
        payload = Response[{{ Name }}Public](result={{ Name }}Public.model_validate(item))
        return RobynResponse(
            status_code=201,
            headers=JSON_HEADERS,
            description=payload.model_dump_json(),
        )

    @app.put("/{{ name }}s/:id", openapi_name="Update {{ Name }}", openapi_tags=["{{ Name }}"])
    async def {{ name }}_update(request: Request, body: {{ Name }}UpdateBody) -> Response[{{ Name }}Public]:
        """Update a {{ name }}."""
        id_ = parse_primary_key(request.path_params["id"])
        async with transaction():
            repo = {{ Name }}Repository()
            item = await repo.update(attr="id", value=id_, payload=body.model_dump(exclude_unset=True))
        return Response[{{ Name }}Public](result={{ Name }}Public.model_validate(item))

    @app.delete("/{{ name }}s/:id", openapi_name="Delete {{ Name }}", openapi_tags=["{{ Name }}"])
    async def {{ name }}_delete(request: Request) -> RobynResponse:
        """Delete a {{ name }}."""
        id_ = parse_primary_key(request.path_params["id"])
        async with transaction():
            repo = {{ Name }}Repository()
            await repo.delete(id_=id_)
        return RobynResponse(status_code=200, headers={}, description="")
