"""The one field set behind ``/status`` on every surface.

The CLI (``cli_session_mixin._show_session_status``), the messaging gateway
(``gateway/slash_commands_status._handle_status_command``) and the TUI backend
(``tui_gateway/methods_session`` ``session.status``) all report the same session facts —
id, home path, title, model route, created / last-activity stamps, lifetime tokens, running
flag. Each used to derive them independently (three ``getattr(agent, "model")`` fallback
chains, three ``updated_at`` candidate scans, three timestamp formats to keep aligned).
They now all call :func:`build_status_fields`; a surface only adds its own header, labels
(the gateway translates through ``t("gateway.status.*")``) and surface-specific extras.
"""

from __future__ import annotations

from datetime import datetime
from pathlib import Path
from typing import Any

STATUS_STAMP = "%Y-%m-%d %H:%M"

UNKNOWN_MODEL = "(unknown)"
UNKNOWN_PROVIDER = "unknown"

# Newest-first: a row carries at most one of these, depending on which writer last touched it.
_LAST_ACTIVITY_FIELDS = ("updated_at", "last_updated_at", "last_activity_at")

# English labels shared by the CLI and TUI renderers (the gateway has its own i18n catalog).
STATUS_LABELS = {
    "session_id": "Session ID",
    "path": "Path",
    "title": "Title",
    "model": "Model",
    "created": "Created",
    "last_activity": "Last Activity",
    "tokens": "Tokens",
    "agent_running": "Agent Running",
}


def timestamp_or(value: Any, default: datetime | None) -> datetime | None:
    """``datetime.fromtimestamp(value)`` or *default* when the value is missing/unparseable."""
    if not value:
        return default
    try:
        return datetime.fromtimestamp(float(value))
    except (TypeError, ValueError, OverflowError, OSError):
        return default


def session_timestamps(meta: dict, created_fallback: datetime | None = None) -> tuple[datetime, datetime]:
    """``(created, last_activity)`` from a SessionDB row; last activity falls back to created."""
    created = timestamp_or(meta.get("started_at"), created_fallback) or datetime.now()
    updated = next(
        (stamp for stamp in (timestamp_or(meta.get(f), None) for f in _LAST_ACTIVITY_FIELDS) if stamp),
        created,
    )
    return created, updated


def build_status_fields(
    session_id: str,
    agent: Any,
    meta: dict | None,
    *,
    title: str | None = None,
    model: str | None = None,
    provider: str | None = None,
    created: datetime | None = None,
    last_activity: datetime | None = None,
    created_fallback: datetime | None = None,
    tokens: int | None = None,
    agent_running: bool = False,
    home: str | Path | None = None,
) -> dict[str, Any]:
    """Common ``/status`` facts, pre-formatted for display.

    ``agent`` wins for model / provider / tokens; the keyword values are the surface's fallback
    (CLI ``self.model``, TUI metadata mirror, gateway's resolved route) and are also what a
    surface passes when it has no live agent. ``created`` / ``last_activity`` override the
    ``meta`` row scan for surfaces whose session store is authoritative (gateway SessionEntry).
    ``home`` is an explicit owning-profile path for multiplexed surfaces; omitted callers keep
    the process/current-profile lookup.
    """
    from hermes_constants import display_hermes_home

    meta = meta or {}
    if created is None or last_activity is None:
        row_created, row_updated = session_timestamps(meta, created_fallback)
        created = created or row_created
        last_activity = last_activity or row_updated
    if tokens is None:
        tokens = getattr(agent, "session_total_tokens", 0) or 0
    row_title = meta.get("title") if title is None else title
    return {
        "session_id": str(session_id or ""),
        "path": display_hermes_home(Path(home) if home else None),
        "title": (row_title or "").strip(),
        "model": getattr(agent, "model", None) or model or "",
        "provider": getattr(agent, "provider", None) or provider or "",
        "created": created.strftime(STATUS_STAMP),
        "last_activity": last_activity.strftime(STATUS_STAMP),
        "tokens": f"{int(tokens or 0):,}",
        "agent_running": bool(agent_running),
    }


def status_lines(fields: dict[str, Any], *keys: str) -> list[str]:
    """``Label: value`` lines for *keys* in order (English surfaces). An empty title is skipped;
    an unresolved model/provider shows a placeholder rather than an empty parenthesis."""
    lines: list[str] = []
    for key in keys:
        value = fields[key]
        if key == "title" and not value:
            continue
        if key == "model":
            value = f"{fields['model'] or UNKNOWN_MODEL} ({fields['provider'] or UNKNOWN_PROVIDER})"
        elif key == "agent_running":
            value = "Yes" if value else "No"
        lines.append(f"{STATUS_LABELS[key]}: {value}")
    return lines
