import uuid

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

from app.core.database import get_db
from app.core.permissions import deny_vendor, require_permission
from app.core.security import AuthContext, get_auth_context
from app.crud.base import CRUDBase
from app.crud import file_transfer, firebase_push, google_apps, sql_providers
from app.crud.rpa_providers import PROVIDERS, RpaError, adapter_for
from app.crud.secrets import connector_config
from app.models.reporting import Connector
from app.schemas.rpa import ConnectorProvider, RpaProcess, RpaProvider

router = APIRouter(prefix="/rpa", tags=["rpa"])
_connectors = CRUDBase(Connector)
providers_router = APIRouter(prefix="/connector-providers", tags=["connectors"])

_PROVIDERS_BY_TYPE = {
    "rpa": PROVIDERS,
    "database": sql_providers.PROVIDERS,
    "file_transfer": file_transfer.PROVIDERS,
    "google": google_apps.PROVIDERS,
    "firebase": firebase_push.PROVIDERS,
}


@providers_router.get("/{connector_type}", response_model=list[ConnectorProvider])
async def list_connector_providers(connector_type: str, _: AuthContext = Depends(get_auth_context)) -> list[dict]:
    """The vendors a provider-driven connector type supports and each one's
    settings — drives the Connectors screen's guided forms."""
    if connector_type not in _PROVIDERS_BY_TYPE:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="no providers for that connector type")
    return _PROVIDERS_BY_TYPE[connector_type]


@router.get("/providers", response_model=list[RpaProvider])
async def list_providers(_: AuthContext = Depends(get_auth_context)) -> list[dict]:
    """The supported RPA platforms and each one's settings — drives the
    Connectors screen's RPA form."""
    return PROVIDERS


@router.get("/connectors/{connector_id}/processes", response_model=list[RpaProcess])
async def list_processes(
    connector_id: uuid.UUID,
    ctx: AuthContext = Depends(get_auth_context),
    db: AsyncSession = Depends(get_db),
    _: AuthContext = Depends(require_permission("tasks", "view")),
    __: AuthContext = Depends(deny_vendor()),
) -> list[dict]:
    """The processes/bots an "rpa" Connector can run — Task Designer's
    picker. Asks the platform live, so it also shows whether the connector
    works."""
    connector = await _connectors.get(db, ctx.tenant_id, connector_id)
    if connector.type != "rpa":
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="not an RPA connector")
    try:
        config = await connector_config(db, ctx.tenant_id, connector)
        return await adapter_for(config).list_processes(config)
    except RpaError as exc:
        raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=str(exc)) from exc
    except Exception as exc:  # noqa: BLE001 - network errors from the platform, surfaced to the designer
        raise HTTPException(status_code=status.HTTP_502_BAD_GATEWAY, detail=f"couldn't reach the RPA platform: {exc}") from exc
