"""Host entrypoint for embedded Python execution (PyO3/XPC)."""

from __future__ import annotations

import json
import os
from typing import Any

from .conversation import build_conversation_context
from .rlm import run_rlm


def _require_field(payload: dict[str, Any], key: str) -> str:
    value = payload.get(key)
    if not isinstance(value, str) or not value.strip():
        raise ValueError(f"Missing required field: {key}")
    return value


def run_for_host(request_json: str) -> str:
    """Run an RLM request from a host process and return JSON."""
    try:
        payload = json.loads(request_json)
    except json.JSONDecodeError as exc:
        return json.dumps({"error": {"type": "JSONDecodeError", "message": str(exc)}}, ensure_ascii=True)

    try:
        question = _require_field(payload, "question")
        db_path = _require_field(payload, "db_path")
        api_key = payload.get("api_key")
        if isinstance(api_key, str) and api_key.strip():
            os.environ["MODELRELAY_API_KEY"] = api_key.strip()
        model = payload.get("model")
        if isinstance(model, str) and model.strip():
            os.environ["RECALL_RLM_MODEL"] = model.strip()
        max_depth = int(payload.get("max_depth", 1))
        max_calls = int(payload.get("max_calls", 10))
        verbose = bool(payload.get("verbose", False))
        conversation_context = payload.get("conversation_context")
        conversation_messages = payload.get("conversation_messages")
        conversation_summary = payload.get("conversation_summary")

        updated_summary = conversation_summary if isinstance(conversation_summary, str) else None
        if isinstance(conversation_context, str) and conversation_context.strip():
            resolved_context = conversation_context.strip()
        elif isinstance(conversation_messages, list) or isinstance(conversation_summary, str):
            resolved_context, updated_summary = build_conversation_context(
                messages=conversation_messages if isinstance(conversation_messages, list) else [],
                summary=conversation_summary if isinstance(conversation_summary, str) else None,
                model=model,
            )
        else:
            resolved_context = None

        result = run_rlm(
            question=question,
            db_path=db_path,
            conversation_context=resolved_context,
            max_depth=max(1, max_depth),
            max_calls=max(1, max_calls),
            verbose=verbose,
        )

        response = {
            "answer": result.answer,
            "retrieved_guids": result.retrieved_guids,
            "iterations": result.iterations,
            "sub_calls_made": result.sub_calls_made,
            "total_tokens": result.total_tokens,
            "error": result.error,
            "conversation_summary": updated_summary,
        }
        return json.dumps(response, ensure_ascii=True)
    except Exception as exc:  # noqa: BLE001 - keep host boundary resilient
        return json.dumps(
            {"error": {"type": exc.__class__.__name__, "message": str(exc)}},
            ensure_ascii=True,
        )
