from typing import Optional, List

from sqlalchemy import func
from sqlalchemy.orm import Session

from models import Service
from repositories.base_repository import BaseRepository
from schemas.service import ServiceSchema, ServiceListItemSchema


class ServiceRepository(BaseRepository[ServiceSchema, Service]):
    def __init__(self, db: Session):
        super().__init__(db, Service)

    def _to_entity(self, db_model: Service) -> Optional[ServiceSchema]:
        return ServiceSchema.model_validate(db_model) if db_model else None

    def _to_db_model(self, entity: ServiceSchema) -> Service:
        return Service(**entity.model_dump())

    async def create_service(self, service_data: ServiceSchema) -> ServiceSchema:
        return await self.create(service_data)

    async def get_by_company_id(self, company_id: int) -> List[ServiceSchema]:
        services = self.db.query(Service).filter(Service.company_id == company_id).all()
        return [self._to_entity(service) for service in services]

    async def count_by_company(self, company_id: int, search: Optional[str] = None) -> int:
        query = self.db.query(func.count(Service.id)).filter(Service.company_id == company_id)
        
        if search:
            query = query.filter(Service.name.ilike(f"%{search}%"))
            
        return query.scalar()

    async def get_by_company_paginated(
        self,
        company_id: int,
        start: int,
        size: int,
        search: Optional[str] = None
    ) -> List[ServiceListItemSchema]:
        query = self.db.query(Service).filter(Service.company_id == company_id)
        
        if search:
            query = query.filter(Service.name.ilike(f"%{search}%"))
            
        services = query.order_by(Service.created_at.desc())\
            .offset(start)\
            .limit(size)\
            .all()
            
        return [ServiceListItemSchema.model_validate(service.__dict__) for service in services]

    async def delete_service(self, service_id: int) -> bool:
        return await self.delete(service_id)