"""Ask prompt builder and auth-error helper for LerimAgent ask flow."""

from __future__ import annotations

from typing import Any


def build_ask_prompt(
    question: str,
    hits: list[dict[str, Any]],
    context_docs: list[dict[str, Any]],
    memory_root: str | None = None,
) -> str:
    """Build the final agent prompt with memory/context evidence blocks."""
    context_lines = [
        (
            f"- {fm.get('id', '?')} conf={fm.get('confidence', '?')}: "
            f"{fm.get('title', '?')} :: {str(fm.get('_body', '')).strip()[:260]}"
        )
        for fm in hits
    ]
    context_block = "\n".join(context_lines) or "(no relevant memories)"

    context_doc_lines = []
    for row in context_docs:
        doc_id = str(row.get("doc_id") or "")
        title = str(row.get("title") or "")
        body = str(row.get("body") or "").strip()
        snippet = " ".join(body.split())[:260]
        context_doc_lines.append(f"- {doc_id}: {title} :: {snippet}")
    context_doc_block = (
        "\n".join(context_doc_lines)
        if context_doc_lines
        else "(no context docs loaded)"
    )

    memory_guidance = ""
    if memory_root:
        memory_guidance = f"""
Memory root: {memory_root}
Layout:
- decisions/*.md — architecture and design decisions
- learnings/*.md — insights, procedures, facts
- summaries/YYYYMMDD/HHMMSS/*.md — session summaries
Each file: YAML frontmatter (id, title, confidence, tags, kind, created) + markdown body.

Search strategy:
1. Use grep to search memory files by keyword (e.g. grep pattern="sqlite" or grep pattern="billing").
2. Use glob to list files in a directory (e.g. glob pattern="decisions/*.md").
3. Use read to get full content of files found by grep/glob.
4. Or use explore() to delegate search to the explorer subagent.
You can also call up to 4 explore() calls in parallel for independent queries.
"""

    return f"""\
Answer the user question using your memory search tools.
- Search the memory root with grep/glob/read or explore() to find relevant memories.
- Search project-first, then global fallback.
- Return evidence with file paths.
- If no relevant memories exist, say that clearly.
- Cite memory ids you used.
{memory_guidance}
Question:
{question}

Pre-fetched hints (may be incomplete — always search with tools):
{context_block}

Context docs:
{context_doc_block}
"""


def looks_like_auth_error(response: str) -> bool:
    """Return whether response text indicates authentication failure."""
    text = str(response or "").lower()
    return (
        "failed to authenticate" in text
        or "authentication_error" in text
        or "oauth token has expired" in text
        or "invalid api key" in text
        or "unauthorized" in text
    )


if __name__ == "__main__":
    prompt = build_ask_prompt(
        "how to deploy",
        [
            {
                "id": "mem-1",
                "confidence": 0.9,
                "title": "Deploy tips",
                "_body": "Use CI.",
            }
        ],
        [{"doc_id": "doc-1", "title": "CI Setup", "body": "Configure pipelines."}],
    )
    assert "how to deploy" in prompt
    assert "mem-1" in prompt
    assert "doc-1" in prompt

    # With memory_root — should include search guidance
    prompt_mr = build_ask_prompt("test", [], [], memory_root="/tmp/test/memory")
    assert "Memory root: /tmp/test/memory" in prompt_mr
    assert "grep" in prompt_mr
    assert "decisions/*.md" in prompt_mr

    # Without memory_root — no guidance block
    prompt_no = build_ask_prompt("test", [], [])
    assert "Memory root" not in prompt_no

    assert looks_like_auth_error("Failed to authenticate with provider")
    assert looks_like_auth_error("authentication_error: invalid key")
    assert not looks_like_auth_error("All good")

    print("ask prompt: all self-tests passed")
