"""Envía una solicitud de chat completion a Ollama (API local compatible con OpenAI)."""

import json
import urllib.request
import urllib.error
from typing import Any


def ollama_chat(
    messages: list[dict],
    model: str = "llama3.1:8b",
    base_url: str = "http://localhost:11434",
    temperature: float = 0.7,
    max_tokens: int = 1024,
) -> dict:
    """Envía una solicitud de chat completion a Ollama.

    Args:
        messages: Lista de mensajes con formato {"role": "system"|"user"|"assistant", "content": str}.
        model: Nombre del modelo Ollama a usar.
        base_url: URL base de la instancia Ollama.
        temperature: Temperatura de generación (0.0 - 1.0).
        max_tokens: Número máximo de tokens a generar.

    Returns:
        Dict con content, model, total_duration_ms y eval_count.

    Raises:
        RuntimeError: Si Ollama no está corriendo o retorna error HTTP.
    """
    url = f"{base_url}/api/chat"
    payload = {
        "model": model,
        "messages": messages,
        "stream": False,
        "options": {
            "temperature": temperature,
            "num_predict": max_tokens,
        },
    }
    body = json.dumps(payload).encode("utf-8")
    req = urllib.request.Request(
        url,
        data=body,
        headers={"Content-Type": "application/json"},
        method="POST",
    )
    try:
        with urllib.request.urlopen(req, timeout=60) as resp:
            raw = resp.read()
    except urllib.error.URLError as exc:
        reason = str(exc.reason) if hasattr(exc, "reason") else str(exc)
        if "connection refused" in reason.lower() or "111" in reason:
            raise RuntimeError(f"Ollama no está corriendo en {base_url}") from exc
        raise RuntimeError(f"Error de conexión con Ollama: {reason}") from exc
    except urllib.error.HTTPError as exc:
        raise RuntimeError(f"Ollama retornó HTTP {exc.code}: {exc.reason}") from exc

    response: dict[str, Any] = json.loads(raw)
    content: str = response["message"]["content"]
    total_duration_ns: int = response.get("total_duration", 0)
    total_duration_ms: int = int(total_duration_ns / 1_000_000)
    eval_count: int = response.get("eval_count", 0)

    return {
        "content": content,
        "model": response.get("model", model),
        "total_duration_ms": total_duration_ms,
        "eval_count": eval_count,
    }
