"""HTML views for MCP runtime health (#430)."""

from __future__ import annotations

import html

from webui.runtime_health import FileHash, RuntimeSnapshot


def _hash_rows(items: tuple[FileHash, ...]) -> str:
    if not items:
        return "<p class='muted'>No hashes available.</p>"
    rows = []
    for item in items:
        digest = item.sha256 or item.error or "unavailable"
        rows.append(
            "<tr>"
            f"<td>{html.escape(item.label)}</td>"
            f"<td><code>{html.escape(item.path)}</code></td>"
            f"<td><code>{html.escape(digest[:16] if item.sha256 else digest)}</code></td>"
            "</tr>"
        )
    return (
        "<table class='registry'><thead><tr>"
        "<th>Artifact</th><th>Path</th><th>SHA-256</th>"
        "</tr></thead><tbody>"
        f"{''.join(rows)}</tbody></table>"
    )


def render_runtime_page(snapshot: RuntimeSnapshot) -> str:
    error_block = ""
    if snapshot.fetch_error:
        error_block = (
            '<div class="stub"><p><strong>Runtime snapshot incomplete:</strong> '
            f"{html.escape(snapshot.fetch_error)}</p></div>"
        )

    identity = snapshot.authenticated_username or "unresolved"
    if snapshot.identity_error:
        identity = f"unresolved ({snapshot.identity_error})"

    stale_block = ""
    if snapshot.stale_runtime_warning:
        stale_block = (
            '<div class="stub"><p><strong>Stale runtime warning:</strong> '
            f"{html.escape(snapshot.stale_runtime_warning)}</p></div>"
        )

    shell = snapshot.shell_health or {}
    shell_summary = (
        f"shell_use_allowed={shell.get('shell_use_allowed')} · "
        f"failures={shell.get('consecutive_spawn_failures')} · "
        f"hard_stopped={shell.get('hard_stopped')}"
    )

    return (
        "<h2>Runtime health</h2>"
        f"<p class='meta'>Project <code>{html.escape(snapshot.project_id)}</code> · "
        f"host <code>{html.escape(snapshot.host)}</code> · "
        f"repo root <code>{html.escape(snapshot.repo_root)}</code></p>"
        f"{error_block}"
        f"{stale_block}"
        "<h3>Active profile</h3>"
        "<table class='detail'>"
        f"<tr><th>Profile</th><td><code>{html.escape(snapshot.profile_name)}</code></td></tr>"
        f"<tr><th>Role kind</th><td>{html.escape(snapshot.role_kind)}</td></tr>"
        f"<tr><th>Identity</th><td>{html.escape(identity)}</td></tr>"
        f"<tr><th>Config model</th><td>{html.escape(snapshot.config_model)}</td></tr>"
        f"<tr><th>Profile mode</th><td>{html.escape(snapshot.profile_mode)} "
        f"({html.escape(snapshot.profile_source)})</td></tr>"
        "</table>"
        "<h3>Server code sync</h3>"
        "<table class='detail'>"
        f"<tr><th>Local HEAD</th><td><code>{html.escape(snapshot.repo_sha or 'unknown')}</code></td></tr>"
        f"<tr><th>Remote {html.escape(snapshot.remote)}/{html.escape('master')}</th>"
        f"<td><code>{html.escape(snapshot.remote_master_sha or 'unknown')}</code></td></tr>"
        f"<tr><th>Commits behind</th><td>{snapshot.commits_behind_master if snapshot.commits_behind_master is not None else 'unknown'}</td></tr>"
        "</table>"
        "<h3>Shell health</h3>"
        f"<p class='meta'>{html.escape(shell_summary)}</p>"
        f"<p class='muted'>{html.escape(str(shell.get('safe_next_action') or ''))}</p>"
        "<h3>Workflow hashes</h3>"
        f"{_hash_rows(snapshot.workflow_hashes)}"
        "<h3>Schema hashes</h3>"
        f"{_hash_rows(snapshot.schema_hashes)}"
        "<h3>Restart / reload</h3>"
        "<p class='muted'>MVP is read-only — restart MCP servers from your IDE/operator "
        "workflow. Related issue: <code>#420</code>. Guidance: "
        f"<code>{html.escape(snapshot.restart_guidance)}</code></p>"
        "<p class='muted'>This page does not expose tokens or perform MCP restarts.</p>"
    )