"""MCP tools for {{ model_name }}.

⚠️ AUTO-GENERATED BY PRISM - DO NOT EDIT
"""

from __future__ import annotations

from contextlib import asynccontextmanager
from typing import Any, AsyncGenerator

from fastmcp import FastMCP
from sqlalchemy.ext.asyncio import AsyncSession

from {{ project_name_snake }}.database import async_session
from {{ project_name_snake }}.services.{{ snake_name }} import {{ model_name }}Service
from {{ project_name_snake }}.schemas.{{ snake_name }} import {{ model_name }}Create, {{ model_name }}Update{% if has_list_filters %}, {{ model_name }}Filter{% endif %}


@asynccontextmanager
async def get_db() -> AsyncGenerator[AsyncSession, None]:
    """Get database session for MCP tools."""
    async with async_session() as session:
        try:
            yield session
            await session.commit()
        except Exception:
            await session.rollback()
            raise


def register_{{ snake_name }}_tools(mcp: FastMCP) -> None:
    """Register {{ model_name }} tools with the MCP server."""

{% if ops_list %}    @mcp.tool(description="{{ list_desc }}")
    async def {{ tool_prefix }}_list(
        page: int = 1,
        page_size: int = 20,
{% if list_filter_params %}{{ list_filter_params }}
{% endif %}    ) -> dict[str, Any]:
        """List {{ plural_name }}.

        Args:
            page: Page number (starts at 1)
            page_size: Number of items per page (max 100)
{% if list_filter_args_doc %}{{ list_filter_args_doc }}
{% endif %}
        Returns:
            Dictionary with items, total count, and pagination info.
        """
        async with get_db() as db:
            service = {{ model_name }}Service(db)
            skip = (page - 1) * min(page_size, 100)
            limit = min(page_size, 100)
{% if has_list_filters %}
            # Build filter object from parameters
{{ list_filter_dict }}
            filter_obj = {{ model_name }}Filter(**filters) if filters else None

            items = await service.list(skip=skip, limit=limit, filters=filter_obj)
            total = await service.count_filtered(filters=filter_obj)
{% else %}
            items = await service.list(skip=skip, limit=limit)
            total = await service.count()
{% endif %}
            return {
                "items": [
                    {k: v for k, v in item.__dict__.items() if not k.startswith("_")}
                    for item in items
                ],
                "total": total,
                "page": page,
                "page_size": limit,
                "has_more": skip + len(items) < total,
            }

{% endif %}{% if ops_read %}    @mcp.tool(description="{{ read_desc }}")
    async def {{ tool_prefix }}_get(id: int) -> dict[str, Any] | None:
        """Get a {{ snake_name }} by ID.

        Args:
            id: The {{ snake_name }} ID.

        Returns:
            The {{ snake_name }} data or None if not found.
        """
        async with get_db() as db:
            service = {{ model_name }}Service(db)
            result = await service.get(id)
            if result is None:
                return None
            return {k: v for k, v in result.__dict__.items() if not k.startswith("_")}

{% endif %}{% if ops_create %}    @mcp.tool(description="{{ create_desc }}")
    async def {{ tool_prefix }}_create(
{{ create_params }}
{% if relationship_params %}{{ relationship_params }}
{% endif %}    ) -> dict[str, Any]:
        """Create a new {{ snake_name }}.

        Args:
{{ create_args_doc }}
{% if relationship_args_doc %}{{ relationship_args_doc }}
{% endif %}
        Returns:
            The created {{ snake_name }} data.
        """
        async with get_db() as db:
            service = {{ model_name }}Service(db)
            data = {{ model_name }}Create({{ create_field_names }})
            result = await service.create(data=data)
{% for rel in relationships %}
{% if rel.type == "many_to_many" %}
            # Handle {{ rel.name }} M2M relationship
            if {{ rel.ids_param }} is not None:
                result = await service.set_{{ rel.name }}(result.id, {{ rel.ids_param }})
{% endif %}
{% endfor %}
            return {k: v for k, v in result.__dict__.items() if not k.startswith("_")}

{% endif %}{% if ops_update %}    @mcp.tool(description="{{ update_desc }}")
    async def {{ tool_prefix }}_update(
        id: int,
{{ update_params }}
{% if relationship_params %}{{ relationship_params }}
{% endif %}    ) -> dict[str, Any] | None:
        """Update an existing {{ snake_name }}.

        Args:
            id: The {{ snake_name }} ID to update.
{{ update_args_doc }}
{% if relationship_args_doc %}{{ relationship_args_doc }}
{% endif %}
        Returns:
            The updated {{ snake_name }} data or None if not found.
        """
        async with get_db() as db:
            service = {{ model_name }}Service(db)
            # Build update data from non-None values
            update_fields = {}
{{ update_field_dict }}
            data = {{ model_name }}Update(**update_fields)
            result = await service.update(id=id, data=data)
            if result is None:
                return None
{% for rel in relationships %}
{% if rel.type == "many_to_many" %}
            # Handle {{ rel.name }} M2M relationship update
            if {{ rel.ids_param }} is not None:
                result = await service.set_{{ rel.name }}(id, {{ rel.ids_param }})
{% endif %}
{% endfor %}
            return {k: v for k, v in result.__dict__.items() if not k.startswith("_")}

{% endif %}{% if ops_delete %}    @mcp.tool(description="{{ delete_desc }}")
    async def {{ tool_prefix }}_delete(id: int) -> bool:
        """Delete a {{ snake_name }}.

        Args:
            id: The {{ snake_name }} ID to delete.

        Returns:
            True if deleted, False if not found.
        """
        async with get_db() as db:
            service = {{ model_name }}Service(db)
            return await service.delete(id=id)

{% endif %}

__all__ = ["register_{{ snake_name }}_tools"]
