"""Client for EB1-GNN routing server.

Configuration flows through ~/.ember/config.yaml only. No env vars.

    # ~/.ember/config.yaml
    eb1_gnn:
      base_url: http://localhost:8082
"""

from __future__ import annotations

import logging
import os
from functools import lru_cache
from pathlib import Path
from typing import TYPE_CHECKING

import yaml

if TYPE_CHECKING:
    import openai

__all__ = ["is_gnn_configured", "get_eb1_client", "clear_config_cache"]

logger = logging.getLogger(__name__)


@lru_cache(maxsize=1)
def _load_config() -> tuple[str | None, str | None]:
    """Load eb1_gnn.base_url and api_key from ~/.ember/config.yaml.

    Returns:
        Tuple of (base_url, api_key), either may be None.
    """
    config_path = Path(os.getenv("EMBER_CONFIG_PATH", "~/.ember/config.yaml"))
    config_path = config_path.expanduser()

    if not config_path.exists():
        logger.debug("Config file not found: %s", config_path)
        return None, None

    with config_path.open("r", encoding="utf-8") as f:
        config = yaml.safe_load(f)

    if not isinstance(config, dict):
        logger.debug("Config file is not a dict")
        return None, None

    eb1_config = config.get("eb1_gnn")
    if not isinstance(eb1_config, dict):
        logger.debug("eb1_gnn section not found in config")
        return None, None

    base_url = eb1_config.get("base_url")
    if isinstance(base_url, str) and base_url.strip():
        base_url = base_url.strip().rstrip("/")
    else:
        base_url = None

    api_key = eb1_config.get("api_key")
    if isinstance(api_key, str) and api_key.strip():
        api_key = api_key.strip()
    else:
        api_key = None

    logger.info(
        "Loaded eb1_gnn config: base_url=%s, api_key=%s",
        base_url,
        "***" if api_key else None,
    )
    return base_url, api_key


def clear_config_cache() -> None:
    """Clear the cached config to force a reload on next access.

    Call this after updating ~/.ember/config.yaml to ensure the gateway
    picks up the new configuration.
    """
    _load_config.cache_clear()
    logger.info("Cleared eb1_gnn config cache")


def is_gnn_configured() -> bool:
    """Check if EB1-GNN routing is configured in ~/.ember/config.yaml."""
    base_url, _ = _load_config()
    return base_url is not None


def get_eb1_client() -> "openai.OpenAI":
    """Get OpenAI-compatible client for EB1-GNN server.

    Uses eb1_gnn.base_url and eb1_gnn.api_key from ~/.ember/config.yaml.
    If api_key is not configured, uses a placeholder (server may reject).

    Raises:
        ValueError: If eb1_gnn.base_url is not configured.
    """
    import openai

    base_url, api_key = _load_config()
    if not base_url:
        logger.error(
            "EB1-GNN not configured. Cache info: %s",
            _load_config.cache_info(),
        )
        raise ValueError(
            "EB1-GNN not configured. Add eb1_gnn.base_url to ~/.ember/config.yaml. "
            "If config was recently updated, call clear_config_cache() or restart the gateway."
        )

    # Use configured API key, or fallback to placeholder
    # (eb1-gnn server will reject if auth is required)
    effective_key = api_key or "not-configured"

    logger.debug("Creating OpenAI client for eb1-gnn: base_url=%s/v1", base_url)
    import httpx

    return openai.OpenAI(
        api_key=effective_key,
        base_url=f"{base_url}/v1",
        timeout=httpx.Timeout(30.0, connect=5.0),
    )
