import json
import os
import time
from typing import Callable, Dict, List

import httpx
from dotenv import load_dotenv


load_dotenv()
DEFAULT_ENDPOINT = os.getenv("GAR_LLM_BASE_URL", "")
DEFAULT_MODEL = os.getenv("GAR_MODEL", "")


def chat_completions(
    messages: List[Dict[str, str]],
    model: str = DEFAULT_MODEL,
    endpoint: str = DEFAULT_ENDPOINT,
    timeout: int = 60,
    retries: int = 2,
    stream_callback: Callable[[str], None] | None = None,
) -> str:
    if not endpoint or not model:
        raise RuntimeError("GAR_LLM_ENDPOINT와 GAR_LLM_MODEL을 .env 또는 환경변수에 설정하세요.")
    url = endpoint.rstrip("/") + "/chat/completions"
    payload = {
        "model": model,
        "messages": messages,
        "temperature": 0.2,
    }

    last_error: Exception | None = None
    for attempt in range(retries + 1):
        try:
            response = httpx.post(url, json=payload, timeout=timeout)
            response.raise_for_status()

            data = response.json()
            # OpenAI-style response 우선 시도
            choices = data.get("choices")
            if choices and isinstance(choices, list) and len(choices) > 0:
                content = choices[0].get("message", {}).get("content")
                if content:
                    return content

            # Ollama-style 등 fallback
            message = data.get("message", {})
            if isinstance(message, dict) and "content" in message:
                return message["content"]

            raise ValueError("Empty content returned from LLM.")
        except Exception as exc:  # noqa: BLE001 - best effort retry
            last_error = exc
            if attempt < retries:
                time.sleep(1)
                continue
            raise RuntimeError(f"LLM request failed: {exc}") from exc
    raise RuntimeError(f"LLM request failed: {last_error}")
