from typing import Optional
from sqlalchemy.ext.asyncio import AsyncSession
from fastapi import APIRouter, Depends, HTTPException, Query, status

from src.core.database import get_db
from src.core.auth import require_enterprise_or_front
from src.services.comandos import ComandoScreenshotService
from src.schemas.comandos import (
    ComandoScreenshotCreate,
    ComandoScreenshotUpdate,
    ComandoScreenshotResponse,
)
from src.core.api_responses import (
    build_success_payload,
    to_schema_dict,
    SuccessResponse,
    ErrorResponse,
)

router = APIRouter(
    prefix="/comandos/screenshot",
    tags=["Comandos Screenshot"],
)

comando_service = ComandoScreenshotService()

@router.get(
    "/pendente",
    summary="Obter comando pendente",
    description=(
        "Retorna o comando de screenshot pendente mais antigo para um "
        "computador.\n\n"
        "Usado pelo cliente para verificar se há comandos a "
        "executar.\n\n"
        "Requer token válido."),
    response_model=SuccessResponse,
    responses={
        200: {
            "description": (
                "Comando pendente ou mensagem de que não há comandos"
            )},
        401: {
            "description": "Credenciais inválidas ou ausentes",
            "model": ErrorResponse},
        500: {
            "description": "Erro interno",
            "model": ErrorResponse},
    })
async def obter_comando_pendente(
    computador_id: str = Query(..., description="ID do computador"),
    db: AsyncSession = Depends(get_db),
    _auth=Depends(require_enterprise_or_front),
):
    comando = await comando_service.obter_comando_pendente(db, computador_id)

    if not comando:
        return build_success_payload(message="Sem comandos pendentes")

    data = to_schema_dict(ComandoScreenshotResponse, comando)
    return build_success_payload(
        data=data, message="Comando pendente encontrado")


@router.get(
    "/{comando_id}",
    summary="Obter comando por ID",
    description=(
        "Retorna os dados de um comando de screenshot específico.\n\n"
        "Usado pelo frontend para verificar o status e resultado.\n\n"
        "Requer token válido."),
    response_model=SuccessResponse,
    responses={
        200: {
            "description": "Dados do comando"},
        404: {
            "description": "Comando não encontrado",
            "model": ErrorResponse},
        401: {
            "description": "Credenciais inválidas ou ausentes",
            "model": ErrorResponse},
        500: {
            "description": "Erro interno",
            "model": ErrorResponse},
    })
async def obter_comando(
    comando_id: int,
    db: AsyncSession = Depends(get_db),
    _auth=Depends(require_enterprise_or_front),
):
    comando = await comando_service.obter_comando(db, comando_id)

    if not comando:
        raise HTTPException(
            status_code=404,
            detail=f"Comando {comando_id} não encontrado"
        )

    data = to_schema_dict(ComandoScreenshotResponse, comando)
    return build_success_payload(data=data, message="Comando encontrado")


@router.get(
    "",
    summary="Listar comandos",
    description=(
        "Lista comandos de screenshot com filtros opcionais.\n\n"
        "Requer token válido."
    ),
    response_model=SuccessResponse,
    responses={
        200: {"description": "Lista de comandos"},
        401: {
            "description": "Credenciais inválidas ou ausentes",
            "model": ErrorResponse},
        500: {"description": "Erro interno", "model": ErrorResponse},
    }
)
async def listar_comandos(
    computador_id: Optional[str] = Query(
        None,
        description="Filtrar por ID do computador",
    ),
    status_filter: Optional[str] = Query(
        None,
        alias="status",
        description="Filtrar por status (pending, completed, error)",
    ),
    db: AsyncSession = Depends(get_db),
    _auth=Depends(require_enterprise_or_front),
):
    comandos = await comando_service.listar_comandos(
        db,
        computador_id=computador_id,
        status=status_filter,
    )

    data = [to_schema_dict(ComandoScreenshotResponse, cmd) for cmd in comandos]
    qtd = len(data)

    if qtd == 0:
        message = "Nenhum comando encontrado"
    elif qtd == 1:
        message = "1 comando encontrado"
    else:
        message = f"{qtd} comandos encontrados"

    return build_success_payload(data=data, message=message)
