"""Deterministic memory snippet prefetch for the main agent (no extra LLM call)."""

from __future__ import annotations

import os
from typing import Any

from utils.redaction import cap_str, redact_text


def _path_within_directory(abs_path: str, dir_abs: str) -> bool:
    """Return True if *abs_path* is *dir_abs* or a path strictly under it."""
    return abs_path == dir_abs or abs_path.startswith(dir_abs + os.sep)


def build_memory_prefetch_with_digest(
    latest_user_text: str,
    *,
    max_chars: int = 1600,
    max_files: int = 3,
    min_query_len: int = 8,
) -> tuple[str, dict[str, Any]]:
    """Return (system block, digest) for Memory Inspector schema v2."""
    q = (latest_user_text or "").strip()
    empty_digest: dict[str, Any] = {"files": [], "chars": 0}
    if len(q) < max(0, int(min_query_len or 0)):
        return "", empty_digest
    try:
        from core import get_workspace_path
        from core.config import get_memory_config
        from utils.memory_scopes import normalize_memory_scope
        from utils.memory_fts_index import search_memory_fts_candidates
        from utils.memory_search_fusion import read_memory_file_capped
    except Exception:
        return "", empty_digest

    workspace = get_workspace_path() or ""
    if not workspace:
        return "", empty_digest
    mem = get_memory_config()
    scope_eff = normalize_memory_scope(None)
    rels, err = search_memory_fts_candidates(
        workspace,
        scope_eff,
        q[:400],
        include_archives=False,
        mem=mem,
        limit=max(6, max_files * 4),
    )
    if err or not rels:
        return "", empty_digest

    base = os.path.abspath(os.path.expanduser(workspace))
    chunks: list[str] = []
    file_rows: list[dict[str, str]] = []
    total = 0
    seen: set[str] = set()
    for rel in rels:
        if rel in seen:
            continue
        seen.add(rel)
        abs_path = os.path.normpath(os.path.join(base, rel))
        if not _path_within_directory(abs_path, base):
            continue
        if not os.path.isfile(abs_path):
            continue
        try:
            txt, _trunc = read_memory_file_capped(abs_path, max_bytes=12_000)
        except Exception:
            continue
        blob = (txt or "").strip()
        if not blob:
            continue
        head = blob[: min(520, len(blob))].replace("\r\n", "\n")
        if len(blob) > len(head):
            head += "\n…"
        preview = cap_str(redact_text(head), 200)
        file_rows.append({"path": rel, "preview": preview})
        chunks.append(f"- `{rel}`: {head}")
        total += len(head)
        if len(chunks) >= max_files or total >= max_chars:
            break
    if not chunks:
        return "", empty_digest
    body = "\n".join(chunks)
    if len(body) > max_chars:
        body = body[: max_chars - 1] + "…"
    block = (
        "\n\n─── Memory prefetch (deterministic FTS snippets; verify with read tools if needed) ───\n"
        + body
        + "\n"
    )
    digest: dict[str, Any] = {
        "files": file_rows,
        "chars": len(block),
        "preview": file_rows[0]["preview"] if file_rows else "",
    }
    return block, digest


def build_memory_prefetch_block(
    latest_user_text: str,
    *,
    max_chars: int = 1600,
    max_files: int = 3,
) -> str:
    """Return a short trusted system-appendix block from FTS-ranked memory files, or ""."""
    block, _digest = build_memory_prefetch_with_digest(
        latest_user_text, max_chars=max_chars, max_files=max_files
    )
    return block


def _continuity_prefetch_query_from_memory_hub(workspace: str) -> str:
    """Build a synthetic FTS query from recent dated MEMORY.md entries."""
    import os

    hub = os.path.join(os.path.abspath(os.path.expanduser(workspace)), "MEMORY.md")
    if not os.path.isfile(hub):
        return "user preferences goals relationships"
    try:
        with open(hub, encoding="utf-8", errors="replace") as f:
            text = f.read()
    except OSError:
        return "user preferences goals relationships"
    lines = [ln.strip() for ln in text.splitlines() if ln.strip().startswith("## ")]
    if not lines:
        return "user preferences goals relationships"
    tail = " ".join(lines[-3:])
    return tail[:400] if len(tail) >= 8 else "user preferences goals relationships"


def build_continuity_memory_prefetch_with_digest(
    *,
    max_chars: int = 1600,
    max_files: int = 3,
) -> tuple[str, dict[str, Any]]:
    """Continuity greeting path: bypass short-query gate using recent MEMORY.md headings."""
    try:
        from core import get_workspace_path

        workspace = get_workspace_path() or ""
    except Exception:
        workspace = ""
    if not workspace:
        return "", {"files": [], "chars": 0}
    q = _continuity_prefetch_query_from_memory_hub(workspace)
    block, digest = build_memory_prefetch_with_digest(
        q,
        max_chars=max_chars,
        max_files=max_files,
        min_query_len=0,
    )
    try:
        from utils.connections_journal import read_connections_journal_tail

        tail = read_connections_journal_tail(workspace, max_chars=min(800, max(0, max_chars // 4)))
        if tail:
            conn_block = f"\n\n### Connections Journal (recent)\n{tail}"
            if len(block) + len(conn_block) <= max_chars:
                block = (block + conn_block).strip()
                digest = dict(digest)
                digest["connections_journal"] = True
    except Exception:
        pass
    return block, digest
