from __future__ import annotations

from typing import Iterable, List

from app.services.code_kb.schema import CodeGraphContext, CodeSearchHit


def _clip(value: str, limit: int) -> str:
    value = value or ""
    if len(value) <= limit:
        return value
    return value[:limit].rstrip() + "\n...[truncated]"


def format_evidence_context(
    hits: Iterable[CodeSearchHit],
    graph_contexts: Iterable[CodeGraphContext],
    max_code_chars: int = 1000,
    max_text_chars: int = 800,
) -> str:
    context_by_node = {item.node_id: item for item in graph_contexts}
    blocks: List[str] = []
    for hit in hits:
        item = hit.evidence
        graph = context_by_node.get(item.node_id)
        lines = [
            f"[Function Evidence #{hit.rank}]",
            f"node_id: {item.node_id}",
            f"name: {item.name}",
            f"qualified_name: {item.qualified_name}",
            f"file: {item.file}",
            f"lines: {item.start_line}-{item.end_line}",
            f"similarity: {hit.similarity:.4f}",
            f"signature: {_clip(item.signature, 300)}",
            f"summary: {_clip(item.summary, max_text_chars)}",
            f"logic_flow: {_clip(item.logic_flow, max_text_chars)}",
            f"calls: {', '.join(item.calls[:20]) or '-'}",
            f"called_by: {', '.join(item.called_by[:20]) or '-'}",
        ]
        if graph:
            lines.append(f"call_chain_evidence: {'; '.join(graph.call_chains[:12]) or '-'}")
        if item.code_snippet:
            lines.extend(["code_snippet:", _clip(item.code_snippet, max_code_chars)])
        blocks.append("\n".join(lines))
    return "\n\n---\n\n".join(blocks)

