"""Which persisted ``thread_id`` values belong on the Swift main Conversation sidebar."""

from __future__ import annotations

# Exact-match ids excluded from sidebar (heartbeat/mesh utilities use their own UX).
_SIDEBAR_EXCLUDED_EXACT: frozenset[str] = frozenset({"__voice_conversation__"})

# Lowercased prefixes: mesh / subagent / ephemeral / background-LLM threads must NOT appear
# beside main chats. Anything you add here is **purely additive** — it can only hide more
# threads, never re-show one that was already hidden. Real user conversations live on
# UUIDv4 thread ids that match none of these prefixes.
_SIDEBAR_EXCLUDED_LOWER_PREFIXES: tuple[str, ...] = (
    # Agent support / infra (legacy list-conversations filters)
    "heartbeat_",
    "background_heartbeat",
    "drive_discovery_",
    "curiosity_",
    "consolidation_",
    "skill_eval_",
    # Curiosity / research-prefetch background LLM calls (curiosity_engine._llm_call passes
    # thread_prefix="prefetch_extract" / "feed_match"; thread_id becomes
    # f"{prefix}_{YYYYMMDD_HHMM}"). These were leaking into the main sidebar with utility-
    # generated titles like "Trust & Tech Failures" because the previous filter only knew
    # about the "curiosity_" prefix.
    "prefetch_extract_",
    "prefetch_",
    "feed_match_",
    # Daily-digest job (mugi_runner builds thread_id=f"daily_digest_{today_str}") and the
    # messaging gateway (thread_id=f"messaging_{adapter}_{channel}_{user}"). Both are
    # internal LLM runs, not user chats.
    "daily_digest_",
    "messaging_",
    # Vault notes (chat_storage uses activity_thread_id=f"vault:{note_id}") and skill
    # curator (thread_id=f"skill_curator:{ts}"). Defensive — currently zero rows in this
    # workspace, but they share the bus and could land in conversation_meta later.
    "vault:",
    "skill_curator:",
    "skill_curator_",
    # Mesh / multi-instance / ephemeral (aligned with active_memory exclusions + recall guard)
    "mesh_",
    "mesh-",
    "mesh_peer_",
    "group_",
    "group-",
    "peer_",
    "peer-",
    "btw_",
    "subagent_",
    # Background actions / incidental writers
    "drive_action",
    "cron_",
    "cronjob",
    "cron-run-",
)


def thread_id_allowed_in_main_conversation_sidebar(thread_id: str | None) -> bool:
    """Threads that should be listed beside normal user chats.

    Mesh sessions, disposable subagents, ``btw_`` forks, cron hooks, etc. stay out of this list.
    """
    tid_raw = str(thread_id or "").strip()
    if not tid_raw:
        return False
    if tid_raw in _SIDEBAR_EXCLUDED_EXACT:
        return False
    tid_l = tid_raw.lower()
    for pref in _SIDEBAR_EXCLUDED_LOWER_PREFIXES:
        if pref and tid_l.startswith(pref):
            return False
    return True
