from typing import Optional, List
from sqlalchemy import select, and_
from sqlalchemy.ext.asyncio import AsyncSession
from src.models.comandos import ComandoScreenshot
from src.schemas.comandos import (
    ComandoScreenshotCreate,
    ComandoScreenshotUpdate
)


class ComandoScreenshotCRUD:
    """CRUD operations for ComandoScreenshot model"""

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

    async def get_pendente_by_computador(
        self,
            db: AsyncSession,
            computador_id: str) -> Optional[ComandoScreenshot]:
        """Busca o comando pendente mais antigo para um computador"""
        result = await db.execute(
            select(ComandoScreenshot)
            .where(
                and_(
                    ComandoScreenshot.computador_id == computador_id,
                    ComandoScreenshot.status == "pending"
                )
            )
            .order_by(ComandoScreenshot.created_at.asc())
            .limit(1)
        )
        return result.scalar_one_or_none()

    async def list(
        self,
        db: AsyncSession,
        *,
        computador_id: Optional[str] = None,
        status: Optional[str] = None,
    ) -> List[ComandoScreenshot]:
        stmt = select(ComandoScreenshot)
        conditions = []

        if computador_id:
            conditions.append(ComandoScreenshot.computador_id == computador_id)
        if status:
            conditions.append(ComandoScreenshot.status == status)

        if conditions:
            stmt = stmt.where(and_(*conditions))

        result = await db.execute(
            stmt.order_by(
                ComandoScreenshot.created_at.desc()
                )
            )
        return list(result.scalars().all())

    async def create(
        self,
            db: AsyncSession,
            payload: ComandoScreenshotCreate) -> ComandoScreenshot:
        obj = ComandoScreenshot(**payload.model_dump())
        db.add(obj)
        await db.commit()
        await db.refresh(obj)
        return obj

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

        for field, value in payload.model_dump(exclude_unset=True).items():
            setattr(obj, field, value)

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


crud_comando = ComandoScreenshotCRUD()
