"""
Local-LLM-Client (Plan B) — Brain-Seite.

Ruft das schnelle lokale LLM (Qwen3 auf der Gamebox) ueber die Bridge:
  Brain → HTTP /internal/local-llm → Bridge → RVS → llm-adapter → llama.cpp

Analog zum Claude-`proxy_client`, nur ueber die Bridge (die ist der RVS-Client;
das Brain bleibt HTTP-only). Der Router im Brain (B1) entscheidet, welche Turns
hierher gehen (einfach) und welche an Claude (schwer / Tool-Bedarf).

Rueckgabe von local_llm_chat: {ok, content, model?, elapsedMs?} oder {ok:False, error}.
Nie werfen — der Aufrufer entscheidet bei ok=False, ob er auf Claude eskaliert.
"""

from __future__ import annotations

import json
import logging
import os
import urllib.error
import urllib.request

logger = logging.getLogger(__name__)

BRIDGE_URL = os.environ.get("BRIDGE_URL", "http://aria-bridge:8090")
# Etwas ueber dem Bridge-seitigen _LLM_TIMEOUT_S (30s), damit der HTTP-Call nicht
# vor dem eigentlichen LLM-Timeout abbricht.
LOCAL_LLM_HTTP_TIMEOUT_SEC = float(os.environ.get("LOCAL_LLM_HTTP_TIMEOUT_SEC", "35"))


def local_llm_chat(messages: list, *, max_tokens: int = 512,
                   temperature: float = 0.7, stop=None) -> dict:
    """Ein Chat-Call ans lokale LLM. messages = [{role, content}, ...].
    Blockierend (urllib) — im Brain laeuft chat() ohnehin im Executor-Thread."""
    if not isinstance(messages, list) or not messages:
        return {"ok": False, "error": "messages leer/ungueltig"}
    req = {"messages": messages, "max_tokens": max_tokens, "temperature": temperature}
    if stop:
        req["stop"] = stop
    try:
        body = json.dumps(req).encode("utf-8")
        http_req = urllib.request.Request(
            f"{BRIDGE_URL}/internal/local-llm", data=body, method="POST",
            headers={"Content-Type": "application/json"},
        )
        with urllib.request.urlopen(http_req, timeout=LOCAL_LLM_HTTP_TIMEOUT_SEC) as resp:
            result = json.loads(resp.read().decode("utf-8", "ignore"))
    except urllib.error.HTTPError as exc:
        try:
            err_data = json.loads(exc.read().decode("utf-8", "ignore"))
            err = err_data.get("error") or str(exc)
        except Exception:
            err = str(exc)
        return {"ok": False, "error": f"local-llm: {err}"}
    except Exception as exc:
        logger.warning("local_llm_chat HTTP-Call fehlgeschlagen: %s", exc)
        return {"ok": False, "error": f"local-llm nicht erreichbar ({exc})"}

    if not isinstance(result, dict) or not result.get("ok"):
        return {"ok": False, "error": (result or {}).get("error", "unbekannt")}
    return result
