# app/lib/embedding_providers/openrouter_provider.py
from typing import List
import httpx
from .base import BaseProvider


class OpenRouterProvider(BaseProvider):
    """
    OpenRouter provider for embeddings and completions.
    OpenRouter is a unified gateway to multiple AI models including Claude, GPT, etc.
    """

    def __init__(
        self,
        api_key: str,
        completion_model: str = "anthropic/claude-3-5-sonnet",
        embedding_model: str = "openai/text-embedding-3-small",
        embedding_dimension: int = 1536
    ):
        """
        Initialize OpenRouter provider.

        Args:
            api_key: OpenRouter API key
            completion_model: Model to use for completions (e.g., 'anthropic/claude-3-5-sonnet')
            embedding_model: Model to use for embeddings (defaults to OpenAI embeddings via OpenRouter)
            embedding_dimension: Dimension of embeddings (default 1536 for OpenAI small)
        """
        if not api_key:
            raise ValueError("OpenRouter API key is required")

        self.api_key = api_key
        self.completion_model = completion_model
        self.embedding_model = embedding_model
        self._dimension = embedding_dimension
        self.base_url = "https://openrouter.ai/api/v1"

    @property
    def dimension(self) -> int:
        return self._dimension

    @property
    def provider_name(self) -> str:
        return "openrouter"

    @property
    def model_name(self) -> str:
        return self.completion_model

    def get_embeddings(self, texts: List[str]) -> List[List[float]]:
        """
        Generate embeddings using OpenRouter API.
        OpenRouter routes to OpenAI embeddings by default.

        Args:
            texts: List of text strings to embed

        Returns:
            List of embedding vectors

        Raises:
            ValueError: If texts is empty
            RuntimeError: If API call fails
        """
        if not texts:
            raise ValueError("Text list cannot be empty")

        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json",
            "HTTP-Referer": "https://crumbcrm.local",
            "X-Title": "CrumbCRM"
        }

        # Ensure model has openai/ prefix for OpenRouter API
        model = self.embedding_model if "/" in self.embedding_model else f"openai/{self.embedding_model}"

        data = {
            "model": model,
            "input": texts
        }

        try:
            with httpx.Client(timeout=30.0) as client:
                response = client.post(
                    f"{self.base_url}/embeddings",
                    headers=headers,
                    json=data
                )
                response.raise_for_status()
                result = response.json()
                return [item["embedding"] for item in result["data"]]

        except httpx.HTTPError as e:
            raise RuntimeError(f"OpenRouter embedding API call failed: {str(e)}")
        except KeyError as e:
            raise RuntimeError(f"Unexpected OpenRouter API response format: {str(e)}")

    def get_completion(self, prompt: str, context: str = "", model: str = None) -> str:
        """
        Generate a completion using OpenRouter API.

        Args:
            prompt: The user's question
            context: Optional context from retrieved documents
            model: Optional model to override default

        Returns:
            The generated response

        Raises:
            ValueError: If prompt is empty
            RuntimeError: If API call fails
        """
        if not prompt:
            raise ValueError("Prompt cannot be empty")

        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json",
            "HTTP-Referer": "https://crumbcrm.local",
            "X-Title": "CrumbCRM"
        }

        messages = []

        # Add system message with context if provided
        # NOTE: If detailed system prompt is passed as context (like in RAGChatService), 
        # we should treat it as system prompt, not just "Answer based on..." wrapper.
        if context:
            # Check if context looks like a full system prompt or just data
            if "You are" in context or "Du bist" in context or "Tu es" in context:
                 messages.append({
                    "role": "system",
                    "content": context
                })
            else:
                messages.append({
                    "role": "system",
                    "content": f"Answer the user's question based on the following context:\n\n{context}"
                })

        # Add user message
        messages.append({
            "role": "user",
            "content": prompt
        })

        data = {
            "model": model or self.completion_model,
            "messages": messages,
            "max_tokens": 2000,
            "temperature": 0.7
        }

        try:
            with httpx.Client(timeout=60.0) as client:
                response = client.post(
                    f"{self.base_url}/chat/completions",
                    headers=headers,
                    json=data
                )
                response.raise_for_status()
                result = response.json()
                return result["choices"][0]["message"]["content"]

        except httpx.HTTPError as e:
            raise RuntimeError(f"OpenRouter completion API call failed: {str(e)}")
        except KeyError as e:
            raise RuntimeError(f"Unexpected OpenRouter API response format: {str(e)}")
