from sqlalchemy import select
from typing import Optional, List
from sqlalchemy.ext.asyncio import AsyncSession

from src.models.times import Time
from src.schemas.times import TimeCreate, TimeUpdate


class TimeCRUD:
    async def get_by_id(
        self,
            db: AsyncSession,
            time_id: int) -> Optional[Time]:
        result = await db.execute(select(Time).where(Time.id == time_id))
        return result.scalar_one_or_none()

    async def get_by_empresa(
        self,
            db: AsyncSession,
            empresa_id: str) -> List[Time]:
        result = await db.execute(
            select(Time).where(Time.empresa_id == empresa_id)
        )
        return list(result.scalars().all())

    async def list(
        self,
        db: AsyncSession,
        *,
        empresa_id: Optional[str] = None,
        nome: Optional[str] = None,
    ) -> List[Time]:
        stmt = select(Time)
        if empresa_id:
            stmt = stmt.where(Time.empresa_id == str(empresa_id))
        if nome:
            stmt = stmt.where(Time.nome.like(f"%{nome}%"))
        result = await db.execute(stmt)
        return list(result.scalars().all())

    async def create(self, db: AsyncSession, payload: TimeCreate) -> Time:
        obj = Time(
            nome=payload.nome,
            descricao=payload.descricao,
            empresa_id=payload.empresa_id,
        )
        db.add(obj)
        await db.commit()
        await db.refresh(obj)
        return obj

    async def update(
        self,
        db: AsyncSession,
        time_id: int,
        payload: TimeUpdate,
    ) -> Optional[Time]:
        obj = await self.get_by_id(db, time_id)
        if not obj:
            return None

        if payload.nome is not None:
            obj.nome = payload.nome
        if payload.descricao is not None:
            obj.descricao = payload.descricao
        if payload.empresa_id is not None:
            obj.empresa_id = payload.empresa_id

        await db.commit()
        await db.refresh(obj)
        return obj

    async def delete(self, db: AsyncSession, time_id: int) -> bool:
        obj = await self.get_by_id(db, time_id)
        if not obj:
            return False
        await db.delete(obj)
        await db.commit()
        return True
