import time

from app.services import ollama_client
from app.services.rag import semantic_search


def heuristic_confidence(done_reason: str | None, output_tokens: int) -> float:
    """NOT a calibrated probability — a rough signal from response shape only:
    penalizes truncated responses and very short answers to open-ended questions."""
    if done_reason not in ("stop", None):
        return 0.35
    if output_tokens < 5:
        return 0.4
    if output_tokens < 20:
        return 0.65
    return 0.85


def send_message(db, project_id, model_name: str, history: list[dict], use_rag: bool) -> dict:
    """history is the full message list including the new user turn as the last item.
    Returns the assistant message dict to append."""
    sources = []
    messages = [{"role": m["role"], "content": m["content"]} for m in history]

    if use_rag:
        last_user = next((m["content"] for m in reversed(history) if m["role"] == "user"), "")
        try:
            sources = semantic_search(db, project_id, last_user, top_k=3)
        except Exception:  # noqa: BLE001
            sources = []
        if sources:
            context_block = "\n\n".join(f"[{i+1}] {c['chunk_text']}" for i, c in enumerate(sources))
            messages.insert(0, {"role": "system", "content": f"Relevant context, cite as [1], [2], etc:\n{context_block}"})

    start = time.perf_counter()
    result = ollama_client.chat(model_name, messages)
    latency_ms = round((time.perf_counter() - start) * 1000, 1)

    return {
        "role": "assistant",
        "content": result["content"],
        "latency_ms": latency_ms,
        "input_tokens": result["prompt_eval_count"],
        "output_tokens": result["eval_count"],
        "confidence": heuristic_confidence(result["done_reason"], result["eval_count"]),
        "confidence_is_heuristic": True,
        "sources": [
            {"chunk_text": s["chunk_text"], "source_filename": s["source_filename"], "score": s["score"]}
            for s in sources
        ],
    }
