"""
cortex/api/routes/config_routes.py — Provider configuration endpoint.

Provides POST /api/v1/config/providers for the host application (OpenClaw
plugin) to push its provider credentials to Cortex at startup. This enables
host mode where Cortex piggybacks on the host's already-configured providers.

The endpoint stores configuration in memory only (not persisted to disk).
It reconfigures the running ProviderRouter so that subsequent LLM/embedding
calls use the host-supplied credentials.

Security: Requires the same auth as all other Cortex endpoints (API key or JWT).
"""

import logging
from typing import Any

from fastapi import APIRouter, Depends, HTTPException, Request, status

from cortex.api.deps import PREFIX, get_plugin

logger = logging.getLogger(__name__)

router = APIRouter()


def _make_routes(verify_api_key):
    """Register provider config routes with the given auth dependency."""

    @router.post(
        f"{PREFIX}/config/providers",
        summary="Configure provider credentials from host",
        tags=["config"],
    )
    async def configure_providers(
        request: Request,
        _: None = Depends(verify_api_key),
        plugin: Any = Depends(get_plugin),
    ) -> dict:
        """Accept provider credentials from the host application.

        Called by the OpenClaw plugin at startup to pass its provider map
        to Cortex. Stores configuration in memory only (not persisted).

        Expected payload::

            {
                "mode": "host",
                "providers": {
                    "openai": {"api_key": "sk-...", "base_url": "..."},
                    "voyage": {"api_key": "pa-...", "base_url": "..."}
                },
                "extraction_model": "gpt-4.1-nano",
                "embedding_model": "voyage-code-3",
                "embedding_dim": 1024
            }

        Returns::

            {"ok": true, "providers_configured": ["openai", "voyage"]}
        """
        try:
            payload = await request.json()
        except Exception:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Invalid JSON body.",
            )

        if not isinstance(payload, dict):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Request body must be a JSON object.",
            )

        providers = payload.get("providers", {})
        if not providers:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="No providers specified in payload.",
            )

        # Get the LLM provider from the plugin
        llm = getattr(plugin, "llm", None)
        if llm is None:
            raise HTTPException(
                status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
                detail="LLM provider not initialised. Cannot configure providers.",
            )

        # The LLM might be wrapped in a ModelRouter — unwrap to find ProviderRouter
        provider_router = llm
        # Check if it's a ModelRouter wrapping a ProviderRouter
        if hasattr(provider_router, "_provider"):
            provider_router = provider_router._provider
        if hasattr(provider_router, "provider") and not hasattr(provider_router, "configure_from_host"):
            # Might be another wrapper layer
            provider_router = getattr(provider_router, "provider", provider_router)

        if not hasattr(provider_router, "configure_from_host"):
            logger.warning(
                "config_routes: LLM provider is %s, not ProviderRouter — "
                "cannot configure from host. Provider config ignored.",
                type(provider_router).__name__,
            )
            return {
                "ok": False,
                "error": "Provider does not support runtime configuration.",
                "providers_configured": [],
            }

        configured = provider_router.configure_from_host(payload)

        logger.info(
            "Provider config received from host: providers=%s, "
            "extraction_model=%s, embedding_model=%s",
            configured,
            payload.get("extraction_model", "?"),
            payload.get("embedding_model", "?"),
        )

        return {
            "ok": True,
            "providers_configured": configured,
        }
