<%~ includeFile('../header.eta', it) %>

from typing import List, Optional, Any

from sqlalchemy.ext.asyncio import AsyncSession

from ..models.<%= it.entityName.toLowerCase() %> import <%= it.entityName %>
from ..schemas.<%= it.entityName.toLowerCase() %> import <%= it.entityName %>Create, <%= it.entityName %>Update
from ..utils.query import QueryBuilder, QueryOptions, PaginatedResult


class <%= it.entityName %>Service:
    """
    Service layer for <%= it.entityName %> CRUD operations.
    """

    def __init__(self, db: AsyncSession):
        self.db = db
        self._qb = QueryBuilder(<%= it.entityName %>, db)

    async def get_many(self, options: QueryOptions) -> PaginatedResult:
        """
        Retrieve a paginated list of <%= it.pluralEntityName %> with filtering, sorting, and joins.
        (nestjsx dialect — {data,count,total,page,pageCount} envelope.)
        """
        return await self._qb.get_many(options)

    async def get_many_list(self, options: QueryOptions) -> List[Any]:
        """
        Retrieve <%= it.pluralEntityName %> as a bare list (PostgREST dialect).
        """
        return await self._qb.get_many_list(options)

    async def get_one(
        self,
        id: Any,
        joins: Optional[List[str]] = None,
    ) -> Optional[<%= it.entityName %>]:
        """
        Retrieve a single <%= it.entityName %> by ID.
        """
        return await self._qb.get_one(id, joins=joins)

    async def create_one(self, data: <%= it.entityName %>Create) -> <%= it.entityName %>:
        """
        Create a new <%= it.entityName %>.
        """
        item = <%= it.entityName %>(**data.model_dump(exclude_unset=True))
        self.db.add(item)
        await self.db.commit()
        await self.db.refresh(item)
        return item

    async def create_many(self, data: List[<%= it.entityName %>Create]) -> List[<%= it.entityName %>]:
        """
        Create multiple <%= it.pluralEntityName %>.
        """
        items = [<%= it.entityName %>(**item.model_dump(exclude_unset=True)) for item in data]
        self.db.add_all(items)
        await self.db.commit()
        for item in items:
            await self.db.refresh(item)
        return items

    async def update_one(
        self,
        id: Any,
        data: <%= it.entityName %>Update,
    ) -> Optional[<%= it.entityName %>]:
        """
        Update an existing <%= it.entityName %>.
        """
        item = await self.get_one(id)
        if not item:
            return None

        update_data = data.model_dump(exclude_unset=True)
        for field, value in update_data.items():
            setattr(item, field, value)

        await self.db.commit()
        await self.db.refresh(item)
        return item

    async def replace_one(
        self,
        id: Any,
        data: <%= it.entityName %>Create,
    ) -> Optional[<%= it.entityName %>]:
        """
        Replace an existing <%= it.entityName %>.
        """
        item = await self.get_one(id)
        if not item:
            return None

        replace_data = data.model_dump()
        for field, value in replace_data.items():
            setattr(item, field, value)

        await self.db.commit()
        await self.db.refresh(item)
        return item

    async def delete_one(self, id: Any) -> bool:
        """
        Delete a <%= it.entityName %> by ID.
        """
        item = await self.get_one(id)
        if not item:
            return False

        await self.db.delete(item)
        await self.db.commit()
        return True
