"""GraphQL mutations for {{ model_name }}.

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

from __future__ import annotations

import re

import strawberry
from strawberry.types import Info

from ..context import Context
from ..types.{{ snake_name }} import {{ model_name }}Type, {{ model_name }}Input, {{ model_name }}UpdateInput, {{ snake_name }}_from_model
from {{ package_name }}.services.{{ snake_name }} import {{ model_name }}Service
from {{ package_name }}.schemas.{{ snake_name }} import {{ model_name }}Create, {{ model_name }}Update


def _camel_to_snake(name: str) -> str:
    """Convert camelCase to snake_case."""
    return re.sub(r'(?<!^)(?=[A-Z])', '_', name).lower()


def _convert_keys_to_snake(data: dict) -> dict:
    """Convert all dictionary keys from camelCase to snake_case."""
    return {_camel_to_snake(k): v for k, v in data.items()}


@strawberry.type
class {{ model_name }}Mutations:
    """GraphQL mutations for {{ model_name }}."""

{% if create_mutation %}
    @strawberry.mutation(description="Create a new {{ model_name }}")
    async def create{{ model_name }}(
        self,
        info: Info[Context, None],
        input: {{ model_name }}Input,
    ) -> {{ model_name }}Type:
        """Create a new {{ model_name }}."""
        service = {{ model_name }}Service(info.context.db)

        # Convert GraphQL input to Pydantic schema (camelCase -> snake_case)
        data = {{ model_name }}Create(**_convert_keys_to_snake(strawberry.asdict(input)))
        result = await service.create(data=data)

        return {{ snake_name }}_from_model(result)

{% endif %}
{% if update_mutation %}
    @strawberry.mutation(description="Update an existing {{ model_name }}")
    async def update{{ model_name }}(
        self,
        info: Info[Context, None],
        id: int,
        input: {{ model_name }}UpdateInput,
    ) -> {{ model_name }}Type | None:
        """Update a {{ model_name }}."""
        service = {{ model_name }}Service(info.context.db)

        # Convert GraphQL input to Pydantic schema, excluding None values (camelCase -> snake_case)
        input_dict = {_camel_to_snake(k): v for k, v in strawberry.asdict(input).items() if v is not None}
        data = {{ model_name }}Update(**input_dict)
        result = await service.update(id=id, data=data)

        if result is None:
            return None
        return {{ snake_name }}_from_model(result)

{% endif %}
{% if delete_mutation %}
    @strawberry.mutation(description="Delete a {{ model_name }}")
    async def delete{{ model_name }}(
        self,
        info: Info[Context, None],
        id: int,
    ) -> bool:
        """Delete a {{ model_name }}."""
        service = {{ model_name }}Service(info.context.db)
        return await service.delete(id=id)

{% endif %}
{% if create_mutation %}
    @strawberry.mutation(description="Create multiple {{ plural_name }}")
    async def create{{ plural_model_name }}(
        self,
        info: Info[Context, None],
        input: list[{{ model_name }}Input],
    ) -> list[{{ model_name }}Type]:
        """Create multiple {{ plural_name }} in a single request."""
        service = {{ model_name }}Service(info.context.db)

        data = [{{ model_name }}Create(**_convert_keys_to_snake(strawberry.asdict(item))) for item in input]
        results = await service.create_many(data=data)

        return [{{ snake_name }}_from_model(item) for item in results]

{% endif %}
{% if update_mutation %}
    @strawberry.mutation(description="Update multiple {{ plural_name }}")
    async def update{{ plural_model_name }}(
        self,
        info: Info[Context, None],
        ids: list[int],
        input: {{ model_name }}UpdateInput,
    ) -> int:
        """Update multiple {{ plural_name }} with the same data. Returns count updated."""
        service = {{ model_name }}Service(info.context.db)

        input_dict = {_camel_to_snake(k): v for k, v in strawberry.asdict(input).items() if v is not None}
        data = {{ model_name }}Update(**input_dict)

        return await service.update_many(ids=ids, data=data)

{% endif %}
{% if delete_mutation %}
    @strawberry.mutation(description="Delete multiple {{ plural_name }}")
    async def delete{{ plural_model_name }}(
        self,
        info: Info[Context, None],
        ids: list[int],
    ) -> int:
        """Delete multiple {{ plural_name }}. Returns count deleted."""
        service = {{ model_name }}Service(info.context.db)
        return await service.delete_many(ids=ids)

{% endif %}

__all__ = ["{{ model_name }}Mutations"]
