from __future__ import annotations

from collections.abc import Mapping
from typing import Any

from langchain_openai import ChatOpenAI

from cleveragents.providers.llm.langchain_chat_provider import LangChainChatProvider


class OpenRouterChatProvider(LangChainChatProvider):
    """LangChain-backed provider adapter for OpenRouter."""

    _BASE_URL = "https://openrouter.ai/api/v1"

    def __init__(
        self,
        *,
        api_key: str,
        model: str = "anthropic/claude-sonnet-4-20250514",
        organization: str | None = None,
        default_headers: Mapping[object, object] | None = None,
        max_retries: int = 3,
        **llm_kwargs: Any,
    ) -> None:
        if not api_key:
            raise ValueError("OpenRouter API key is required")

        sanitized_headers = self._sanitize_headers(default_headers)
        org_value = organization.strip() if organization else ""
        if org_value:
            if sanitized_headers is None:
                sanitized_headers = {}
            sanitized_headers.setdefault("HTTP-Referer", org_value)
            sanitized_headers.setdefault("X-Title", org_value)

        def factory(resolved_model: str) -> ChatOpenAI:
            headers_copy = dict(sanitized_headers) if sanitized_headers else None
            kwargs: dict[str, Any] = {
                "model": resolved_model,
                "openai_api_base": self._BASE_URL,
                "openai_api_key": api_key,
            }
            if headers_copy:
                kwargs["default_headers"] = headers_copy
            if llm_kwargs:
                kwargs.update(llm_kwargs)
            return ChatOpenAI(**kwargs)

        super().__init__(
            name="openrouter",
            model_id=model,
            llm_factory=factory,
            max_retries=max_retries,
            supports_streaming=True,
        )

    @staticmethod
    def _sanitize_headers(
        headers: Mapping[object, object] | None,
    ) -> dict[str, str] | None:
        if not headers:
            return None
        sanitized: dict[str, str] = {}
        for key, value in headers.items():
            sanitized[str(key)] = str(value)
        return sanitized
