import os
from typing import List, Dict, Any, AsyncGenerator
from pydantic import BaseModel
from litellm import acompletion


class Message(BaseModel):
    role: str
    content: str


class LLMClient:
    def _get_config(self) -> Dict[str, Any]:
        """settings_manager에서 현재 설정을 동적으로 읽음"""
        from nexus_agent.core.settings_manager import settings_manager

        llm = settings_manager.llm
        api_key = llm.api_key or self._resolve_api_key(llm.model)

        config: Dict[str, Any] = {
            "model": llm.model,
            "api_key": api_key,
            "temperature": llm.temperature,
            "max_tokens": llm.max_tokens,
        }
        if llm.api_base:
            config["api_base"] = llm.api_base
        return config

    @staticmethod
    def _resolve_api_key(model: str) -> str | None:
        """모델 프로바이더에 따라 환경변수에서 API 키 자동 선택"""
        model_lower = model.lower()
        if model_lower.startswith(("gpt-", "openai/", "o1", "o3", "o4")):
            return os.getenv("OPENAI_API_KEY")
        elif model_lower.startswith(("claude-", "anthropic/")):
            return os.getenv("ANTHROPIC_API_KEY")
        elif model_lower.startswith(("grok-", "xai/")):
            return os.getenv("XAI_API_KEY")
        elif model_lower.startswith("openrouter/"):
            return os.getenv("OPENROUTER_API_KEY")
        elif model_lower.startswith(("gemini/", "google/")):
            return os.getenv("GOOGLE_API_KEY")
        # hosted_vllm, ollama 등은 키 불필요할 수 있음
        return os.getenv("GOOGLE_API_KEY") or os.getenv("OPENAI_API_KEY")

    def get_system_prompt(self) -> str:
        from nexus_agent.core.settings_manager import settings_manager
        return settings_manager.llm.system_prompt

    async def chat_completion(self, messages: List[Dict[str, Any]], tools: List[Dict[str, Any]] = None) -> Dict[str, Any]:
        config = self._get_config()
        kwargs = {
            **config,
            "messages": messages,
        }
        if tools:
            kwargs["tools"] = tools
            kwargs["tool_choice"] = "auto"

        response = await acompletion(**kwargs)
        return response.model_dump()

    async def chat_stream(self, messages: List[Dict[str, Any]]) -> AsyncGenerator[str, None]:
        config = self._get_config()
        kwargs = {
            **config,
            "messages": messages,
            "stream": True,
        }

        response = await acompletion(**kwargs)
        async for chunk in response:
            content = chunk.choices[0].delta.content
            if content:
                yield content


llm_client = LLMClient()
