"""Drug service layer with caching."""
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.models.drug import Drug
from app.services.cache_service import CacheService


class DrugService:
    def __init__(self, db: AsyncSession, cache: CacheService | None = None):
        self.db = db
        self.cache = cache

    async def get_by_id(self, drug_id: int) -> Drug | None:
        """Fetch a drug by ID, using cache when available."""
        cache_key = f"drug:{drug_id}"
        if self.cache:
            cached = await self.cache.get(cache_key)
            if cached:
                return cached

        result = await self.db.execute(select(Drug).where(Drug.id == drug_id))
        drug = result.scalar_one_or_none()

        if drug and self.cache:
            await self.cache.set(cache_key, drug, ttl_category="detail")

        return drug

    async def search(self, query: str, page: int = 1, size: int = 20) -> tuple[list[Drug], int]:
        """Search drugs by name with pagination."""
        from sqlalchemy import func

        offset = (page - 1) * size
        base = select(Drug).where(Drug.item_name.ilike(f"%{query}%"))

        total_result = await self.db.execute(select(func.count()).select_from(base.subquery()))
        total = total_result.scalar_one()

        result = await self.db.execute(base.offset(offset).limit(size).order_by(Drug.item_name))
        items = list(result.scalars().all())

        return items, total
