"""Gemini, Groq, and OpenRouter API calls."""

from app.utils.constants import (
    AI_TEMPERATURE,
    GEMINI_KEYS,
    GROQ_KEYS,
    HTTP_TIMEOUT,
    OPENROUTER_KEYS,
)
from app.utils.helpers import get_http_client, is_gemma_model


async def call_gemini(
    api_key: str,
    model: str,
    system_prompt: str,
    user_prompt: str,
    timeout: float = HTTP_TIMEOUT,
    strict_json: bool = True,
) -> str:
    url = (
        f"https://generativelanguage.googleapis.com/v1beta/models/"
        f"{model}:generateContent?key={api_key}"
    )
    use_strict = strict_json and not is_gemma_model(model)
    generation_config: dict = {"temperature": AI_TEMPERATURE, "maxOutputTokens": 4096}
    if use_strict:
        generation_config["responseMimeType"] = "application/json"

    payload = {
        "contents": [
            {"role": "user", "parts": [{"text": f"{system_prompt}\n\n{user_prompt}"}]},
        ],
        "generationConfig": generation_config,
    }

    client = get_http_client()
    response = await client.post(url, json=payload, timeout=timeout)
    response.raise_for_status()
    data = response.json()

    candidates = data.get("candidates", [])
    if not candidates:
        raise ValueError("Gemini returned no candidates")
    parts = candidates[0].get("content", {}).get("parts", [])
    if not parts:
        raise ValueError("Gemini returned empty content")
    text = parts[0].get("text", "")
    if not text or not text.strip():
        raise ValueError("Gemini returned empty text")
    return text


async def call_groq(
    api_key: str,
    model: str,
    system_prompt: str,
    user_prompt: str,
    timeout: float = HTTP_TIMEOUT,
    strict_json: bool = True,
) -> str:
    url = "https://api.groq.com/openai/v1/chat/completions"
    headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
    payload: dict = {
        "model": model,
        "temperature": AI_TEMPERATURE,
        "messages": [
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": user_prompt},
        ],
    }
    if strict_json and not is_gemma_model(model):
        payload["response_format"] = {"type": "json_object"}

    client = get_http_client()
    response = await client.post(url, headers=headers, json=payload, timeout=timeout)
    response.raise_for_status()
    data = response.json()

    choices = data.get("choices", [])
    if not choices:
        raise ValueError("Groq returned no choices")
    content = choices[0].get("message", {}).get("content", "")
    if not content or not str(content).strip():
        raise ValueError("Groq returned empty content")
    return content


async def call_openrouter(
    api_key: str,
    model: str,
    system_prompt: str,
    user_prompt: str,
    timeout: float = HTTP_TIMEOUT,
    strict_json: bool = True,
) -> str:
    url = "https://openrouter.ai/api/v1/chat/completions"
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
        "HTTP-Referer": "http://localhost:8000",
        "X-Title": "Lab Report Analyzer",
    }
    payload: dict = {
        "model": model,
        "temperature": AI_TEMPERATURE,
        "messages": [
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": user_prompt},
        ],
    }
    if strict_json and not is_gemma_model(model):
        payload["response_format"] = {"type": "json_object"}

    client = get_http_client()
    response = await client.post(url, headers=headers, json=payload, timeout=timeout)
    response.raise_for_status()
    data = response.json()

    choices = data.get("choices", [])
    if not choices:
        raise ValueError("OpenRouter returned no choices")
    content = choices[0].get("message", {}).get("content", "")
    if not content or not str(content).strip():
        raise ValueError("OpenRouter returned empty content")
    return content


def get_gemini_keys() -> list[str]:
    return list(GEMINI_KEYS)


def get_groq_keys() -> list[str]:
    return list(GROQ_KEYS)


def get_openrouter_keys() -> list[str]:
    return list(OPENROUTER_KEYS)
