"""External source endpoints: enumerate sources and trigger imports.

Listing/health are read-only (any authenticated user). Scanning a source is an
admin action and runs in a worker — the endpoint only enqueues it.
"""

from typing import Any

from fastapi import APIRouter

from app.api.deps import CurrentUser, SourceRegistryDep, SuperUser
from app.api.schemas.source import ScanResponse, SourceHealthOut, SourceInfoOut
from app.domain.errors import DependencyUnavailableError
from app.workers.queue import enqueue

router = APIRouter(prefix="/sources", tags=["sources"])


@router.get("")
async def list_sources(_: CurrentUser, registry: SourceRegistryDep) -> list[SourceInfoOut]:
    return [SourceInfoOut.from_entity(info) for info in registry.infos()]


@router.post("/{source}/scan")
async def scan_source(source: str, user: SuperUser, registry: SourceRegistryDep) -> ScanResponse:
    backend = registry.indexable(source)  # 404 if unknown, 422 if not indexable
    if not backend.is_available():
        raise DependencyUnavailableError(f"Source {source!r} is not available.")
    job_id = await enqueue("scan_local_folder", source=source, added_by=str(user.id))
    return ScanResponse(source=source, job_id=job_id)


@router.get("/{source}/health")
async def source_health(
    source: str, _: CurrentUser, registry: SourceRegistryDep
) -> SourceHealthOut:
    backend = registry.get(source)  # 404 if unknown
    return SourceHealthOut(name=backend.name, available=backend.is_available())


@router.get("/{source}/search")
async def search_source(source: str, _: CurrentUser) -> Any:
    # Search is for fetch-style sources (youtube, …) — not yet implemented.
    ...
