"""FastAPI router factory for search endpoints."""

from __future__ import annotations

from typing import Any

from search.config import get_search
from search.models import SearchQuery, SearchResponse
from search.service import SearchService
from errors import BusinessLogicError
from api_core.responses import ApiResponse, PaginatedResponse


def create_search_router(
    prefix: str = "/search",
    tags: list[str] | None = None,
    admin_dependency: Any = None,
) -> Any:
    """Create a FastAPI ``APIRouter`` with search endpoints.

    Args:
        prefix: URL prefix for all routes.
        tags: OpenAPI tags for the router.
        admin_dependency: Optional FastAPI ``Depends()`` for the reindex endpoint.

    Returns:
        A configured ``fastapi.APIRouter``.

    Endpoints:
        - ``POST /{index}`` -- Execute a search query.
        - ``GET /{index}/suggest`` -- Autocomplete suggestions.
        - ``POST /{index}/reindex`` -- Trigger a full reindex (admin).
    """
    try:
        from fastapi import APIRouter, Depends, Query
    except ImportError as exc:
        raise ImportError(
            "Install willian-search[fastapi] to use the router."
        ) from exc

    router = APIRouter(prefix=prefix, tags=tags or ["search"])

    def _get_service() -> SearchService:
        return SearchService(get_search())

    @router.post("/{index}", response_model=SearchResponse)
    async def search_index(
        index: str,
        query: SearchQuery,
        service: SearchService = Depends(_get_service),
    ) -> SearchResponse:
        """Execute a full-text search against the given index."""
        return await service.search(index, query)

    @router.get("/{index}/suggest", response_model=SearchResponse)
    async def suggest(
        index: str,
        q: str = Query(..., min_length=1, description="Autocomplete query"),
        limit: int = Query(5, ge=1, le=20, description="Max suggestions"),
        service: SearchService = Depends(_get_service),
    ) -> SearchResponse:
        """Return autocomplete suggestions for the given prefix."""
        query = SearchQuery(query=q, per_page=limit, highlight=True)
        return await service.search(index, query)

    reindex_deps: list[Any] = []
    if admin_dependency is not None:
        reindex_deps.append(Depends(admin_dependency))

    @router.post("/{index}/reindex", dependencies=reindex_deps)
    async def reindex(
        index: str,
        service: SearchService = Depends(_get_service),
    ) -> dict[str, str]:
        """Trigger a full reindex of the given index.

        This is an admin-only endpoint. A ``fetch_fn`` must be registered
        separately; this endpoint is a placeholder for triggering the process.
        """
        raise BusinessLogicError(
            f"Reindex for '{index}' requires a registered fetch function. "
            "Use SearchService.reindex() directly with your data source."
        )

    return router
