from src.controllers.app_updates import router as app_updates_router
from src.controllers.comandos import router as comandos_router
from src.controllers.usuarios_times import router as usuarios_times_router
from src.controllers.classificacao import router as classificacao_router
from src.controllers.visualizacoes import router as visualizacoes_router
from src.controllers.computadores import router as computadores_router
from src.controllers.atividades import router as atividades_router
from src.controllers.usuarios import router as usuarios_router
from src.controllers.empresas import router as empresas_router
from src.controllers.palavras import router as palavras_router
from src.controllers.bucket import router as bucket_router
from src.controllers.times import router as times_router
import traceback
import logging

from fastapi.responses import JSONResponse
from fastapi.middleware.gzip import GZipMiddleware
from fastapi import FastAPI, Request, status, HTTPException
from fastapi.openapi.utils import get_openapi

logging.basicConfig(level=logging.WARNING)
logger = logging.getLogger(__name__)


tags_metadata = [
    {
        "name": "Health",
        "description": "Verificações de disponibilidade e status do serviço.",
    },
    {
        "name": "Empresas",
        "description": "Cadastro e gestão de empresas (CRUD e consultas).",
    },
    {
        "name": "Computadores",
        "description": "Gestão de computadores vinculados às empresas."
    },
    {
        "name": "Atividades",
        "description": "Ingestão e consulta de atividades dos computadores."
    },
    {
        "name": "Classificação",
        "description": "Gestão de classificações de atividades."
    },
    {
        "name": "Times",
        "description": "Gestão de times vinculados às empresas."
    },
    {
        "name": "Usuarios",
        "description": "Gestão de usuários do sistema."
    },
    {
        "name": "Usuarios-Times",
        "description": "Vínculo entre usuários e times."
    },
    {
        "name": "Palavras",
        "description": "Gerenciamento de palavras-chave."
    },
    {
        "name": "Bucket",
        "description": "Upload e download de imagens no Backblaze B2."
    },
    {
        "name": "Comandos Screenshot",
        "description": "Gerenciamento de comandos de screenshot remotos."
    },
    {
        "name": "Versões",
        "description": "Gerenciamento de versões do aplicativo launcher."
    },
]

app = FastAPI(
    title="POMIND-API",
    version="2.3.0",
    openapi_tags=tags_metadata
)

app.add_middleware(GZipMiddleware, minimum_size=1000)

app.include_router(atividades_router)
app.include_router(empresas_router)
app.include_router(computadores_router)
app.include_router(classificacao_router)
app.include_router(times_router)
app.include_router(usuarios_router)
app.include_router(visualizacoes_router)
app.include_router(usuarios_times_router)
app.include_router(palavras_router)
app.include_router(bucket_router, prefix="/api", tags=["Bucket"])
app.include_router(comandos_router)
app.include_router(app_updates_router)


@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
    """Captura todas as exceções não tratadas e retorna detalhes do erro."""
    if isinstance(exc, HTTPException):
        raise exc

    traceback_str = "".join(
        traceback.format_exception(
            type(exc),
            exc,
            exc.__traceback__,
        )
    )

    logger.error(f"Erro em {request.url}: {str(exc)}\n{traceback_str}")

    return JSONResponse(
        status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
        content={
            "error": {
                "code": "INTERNAL_SERVER_ERROR",
                "message": str(exc),
                "details": traceback_str,
                "path": str(request.url),
            }
        },
    )


@app.get(
    "/health",
    tags=["Health"],
    responses={
        200:
            {
                "description": "Serviço operacional"
            }
    },
    openapi_extra={
        "responses": {
            "200": {
                "content": {"application/json": {"examples": {"status": "ok"}}}
            }
        }
    })
async def health_check():
    try:
        logger.info("Health check solicitado")
        return {"status": "ok"}
    except Exception as e:
        logger.error(f"Erro no health check: {str(e)}", exc_info=True)
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Health check falhou: {str(e)}"
        )


def custom_openapi():
    if app.openapi_schema:
        return app.openapi_schema
    schema = get_openapi(
        title=app.title,
        version=app.version,
        description=app.description,
        routes=app.routes,
    )
    components = schema.setdefault("components", {})
    security_schemes = components.setdefault("securitySchemes", {})
    security_schemes["bearerAuth"] = {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "Token",
        "description": "Use Authorization: Bearer <token>.",
    }
    security_schemes["enterpriseTokenHeader"] = {
        "type": "apiKey",
        "in": "header",
        "name": "X-Enterprise-Token",
        "description": "Alternativa: envie o token de Empresa no header.",
    }
    schema["security"] = [
        {"bearerAuth": []},
        {"enterpriseTokenHeader": []},
    ]

    for path, methods in schema.get("paths", {}).items():
        if path == "/health":
            for method_obj in methods.values():
                method_obj["security"] = []
    app.openapi_schema = schema
    return app.openapi_schema


app.openapi = custom_openapi
