"""Render bullpen-doctor --json output as a self-contained HTML fragment."""

from html import escape


def render_status(doctor_json):
    """Return a single HTML fragment string describing the doctor's report.

    Degrades instead of raising when the report is missing or partial. bullpen-doctor is
    not installed on every host that serves the page (noether isn't), so build_page got
    `{}` here, KeyError'd, and the WHOLE page — transcript included — was replaced by
    "Status page unavailable". The transcript is the point of the page; a missing status
    widget must cost you the widget, not the room."""
    # Empty report -> empty fragment (contract pinned by test_bullseye_api.py:
    # "doctor failure must degrade status to empty, not crash").
    if not doctor_json:
        return ""

    doctor_json = dict(doctor_json)
    ts = doctor_json.get("ts", "?")
    hosts = doctor_json.get("hosts") or {}
    agents = doctor_json.get("agents") or {}
    grinds = doctor_json.get("grinds") or {}
    verdict = doctor_json.get("verdict", "")
    flags = doctor_json.get("flags") or []

    parts = []

    # Timestamp
    parts.append(f'<div style="font-family:monospace;font-size:12px;color:#666;">{escape(str(ts))}</div>')

    # Hosts table
    if hosts:
        parts.append('<table>')
        for hostname in sorted(hosts):
            info = hosts[hostname]
            load = info["load"]
            temp_c = info["temp_c"]
            mem = info["mem"]
            reachable = info["reachable"]

            # None-safe rendering
            load_str = escape(str(load)) if load is not None else "-"
            temp_str = escape(str(temp_c)) if temp_c is not None else "-"
            mem_str = escape(str(mem)) if mem is not None else "-"

            # Hot styling
            hot_style = ' style="background-color:#ffe0e0;font-weight:bold;"' if temp_c is not None and temp_c >= 80 else ''

            unreachable_text = ' <span style="color:red;">unreachable</span>' if not reachable else ''

            parts.append(
                f'<tr data-host="{escape(hostname, quote=True)}"{hot_style}>'
                f'<td>{escape(hostname)}</td>'
                f'<td>{load_str}</td>'
                f'<td>{temp_str}</td>'
                f'<td>{mem_str}</td>'
                f'<td>{unreachable_text}</td>'
                f'</tr>'
            )
        parts.append('</table>')
    else:
        parts.append('<div>No hosts</div>')

    # Agents
    if agents:
        parts.append('<div style="margin-top:8px;"><strong>Agents:</strong></div>')
        for agent in agents:
            name = agent["agent"]
            model = agent["model"]
            age = agent["age"]
            parts.append(
                f'<div data-agent="{escape(name, quote=True)}">'
                f'{escape(name)}: {escape(model)} ({escape(age)})'
                f'</div>'
            )
    else:
        parts.append('<div style="margin-top:8px;">No agents</div>')

    # Grinds
    parts.append(f'<div data-grinds="{len(grinds)}" style="margin-top:8px;">')
    if grinds:
        parts.append('<strong>Grinds:</strong>')
        for g in grinds:
            parts.append(f'<div>{escape(g["age"])}</div>')
    else:
        parts.append('No grinds')
    parts.append('</div>')

    # Verdict
    verdict_styles = {
        "busy-healthy": ' style="color:green;font-weight:bold;"',
        "idle": ' style="color:grey;font-weight:bold;"',
        "needs-a-look": ' style="color:orange;font-weight:bold;"',
    }
    vs = verdict_styles.get(verdict, '')
    parts.append(
        f'<div data-verdict="{escape(verdict, quote=True)}"{vs}>'
        f'{escape(verdict)}'
        f'</div>'
    )

    return ''.join(parts)
