"""Local fallback status-page helpers extracted from `hiveos.observe`."""

from __future__ import annotations

import html
import json
import os
import threading
import time
import webbrowser
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from urllib.parse import quote_plus


def build_status_page_html(
    *,
    run_id,
    run_record,
    target_url,
    active_trace_log_path,
    run_file,
    read_trace_events_for_run,
    list_run_records,
    shorten,
):
    record = dict(run_record or {})
    rid_text = str(run_id or "")
    status = html.escape(str(record.get("status") or "unknown"))
    command = html.escape(str(record.get("command") or ""))
    cwd = html.escape(str(record.get("cwd") or ""))
    started = html.escape(str(record.get("started_at_ms") or ""))
    finished = html.escape(str(record.get("finished_at_ms") or ""))
    trace_log_path_raw = str(record.get("trace_log_path") or active_trace_log_path())
    trace_path = html.escape(trace_log_path_raw)
    run_file_text = html.escape(str(run_file(run_id)))
    target = html.escape(str(target_url or ""))
    rid = html.escape(rid_text)
    duration_ms = int(record.get("duration_ms") or 0)
    duration = html.escape(f"{duration_ms} ms")
    exit_code = html.escape(str(record.get("exit_code") if record.get("exit_code") is not None else ""))

    events = read_trace_events_for_run(rid_text, limit=120, trace_log_path=trace_log_path_raw)
    recent_events = events[-15:]
    stdout_tail = []
    stderr_tail = []
    for event in events:
        event_type = str(event.get("event_type") or "")
        payload = event.get("payload")
        payload = payload if isinstance(payload, dict) else {}
        text = str(payload.get("text") or "").strip()
        if not text:
            continue
        if event_type == "observe_stdout":
            stdout_tail.append(text)
        elif event_type == "observe_stderr":
            stderr_tail.append(text)
    stdout_tail = stdout_tail[-20:]
    stderr_tail = stderr_tail[-20:]

    recent_rows = []
    for event in recent_events:
        event_type = str(event.get("event_type") or "")
        outcome = str(event.get("outcome") or "")
        payload = event.get("payload")
        payload = payload if isinstance(payload, dict) else {}
        payload_text = shorten(json.dumps(payload, separators=(",", ":")), limit=220)
        line = f"{event_type} | {outcome} | {payload_text}"
        recent_rows.append(html.escape(line))
    recent_rows_html = "<br/>".join(recent_rows) if recent_rows else "<em>(no events)</em>"
    stdout_html = "<br/>".join(html.escape(item) for item in stdout_tail) if stdout_tail else "<em>(none)</em>"
    stderr_html = "<br/>".join(html.escape(item) for item in stderr_tail) if stderr_tail else "<em>(none)</em>"

    peer_records = [item for item in list_run_records(limit=12) if str(item.get("run_id") or "").strip() != rid_text][:8]
    peer_lines = []
    for item in peer_records:
        peer_id = str(item.get("run_id") or "").strip()
        if not peer_id:
            continue
        peer_status = str(item.get("status") or "unknown")
        peer_duration = int(item.get("duration_ms") or 0)
        peer_cmd = shorten(str(item.get("command") or ""), limit=90)
        peer_lines.append(html.escape(f"{peer_id} | {peer_status} | {peer_duration} ms | {peer_cmd}"))
    peers_html = "<br/>".join(peer_lines) if peer_lines else "<em>(no other runs)</em>"

    action_lines = [
        f"hive trace show {rid_text} --limit 120",
        f"hive trace diagnose {rid_text}",
        f"hive trace replay {rid_text} --no-open",
        "hive trace ls --limit 10",
    ]
    actions_html = "<br/>".join(html.escape(line) for line in action_lines)
    return f"""<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Hive Trace Status</title>
  <style>
    body {{ background: #0d0d0f; color: #e8e8ea; font-family: Segoe UI, Arial, sans-serif; margin: 0; padding: 20px; }}
    .card {{ border: 1px solid #3a3a3f; border-radius: 12px; padding: 16px; background: #17171a; max-width: 1040px; }}
    h1 {{ margin: 0 0 8px; font-size: 20px; color: #f4f4f5; }}
    h2 {{ margin: 16px 0 8px; font-size: 15px; color: #e3e3e6; }}
    p {{ margin: 8px 0; color: #b4b4ba; }}
    .kv {{ margin-top: 12px; font-family: Consolas, Menlo, monospace; white-space: pre; overflow-x: auto; }}
    .row {{ margin: 4px 0; }}
    .block {{ margin-top: 12px; border: 1px solid #2f2f34; border-radius: 10px; padding: 10px; background: #101013; overflow-x: auto; }}
    a {{ color: #d0d0d6; }}
    code {{ color: #f1f1f2; }}
  </style>
</head>
<body>
  <div class="card">
    <h1>Hive Trace Status</h1>
    <p>Frontend UI is unreachable right now, so this local fallback page was served by Hive.</p>
    <div class="kv">
      <div class="row"><strong>run_id:</strong> <code>{rid}</code></div>
      <div class="row"><strong>status:</strong> <code>{status}</code></div>
      <div class="row"><strong>command:</strong> <code>{command}</code></div>
      <div class="row"><strong>cwd:</strong> <code>{cwd}</code></div>
      <div class="row"><strong>started_at_ms:</strong> <code>{started}</code></div>
      <div class="row"><strong>finished_at_ms:</strong> <code>{finished}</code></div>
      <div class="row"><strong>duration:</strong> <code>{duration}</code></div>
      <div class="row"><strong>exit_code:</strong> <code>{exit_code}</code></div>
      <div class="row"><strong>run_file:</strong> <code>{run_file_text}</code></div>
      <div class="row"><strong>trace_log_path:</strong> <code>{trace_path}</code></div>
      <div class="row"><strong>target_ui:</strong> <a href="{target}" target="_blank" rel="noopener noreferrer">{target}</a></div>
    </div>
    <h2>CLI Actions</h2>
    <div class="block kv">{actions_html}</div>
    <h2>Recent Event Stream</h2>
    <div class="block kv">{recent_rows_html}</div>
    <h2>stdout tail</h2>
    <div class="block kv">{stdout_html}</div>
    <h2>stderr tail</h2>
    <div class="block kv">{stderr_html}</div>
    <h2>Recent Runs</h2>
    <div class="block kv">{peers_html}</div>
    <p>Once your frontend is running, open the target UI link above.</p>
  </div>
</body>
</html>"""


def open_run_status_fallback(
    *,
    target_url,
    run_id,
    read_run_record,
    build_status_page_html_fn,
):
    served = threading.Event()
    record = read_run_record(run_id) or {}
    page_html = build_status_page_html_fn(run_id=run_id, run_record=record, target_url=target_url)

    class _StatusHandler(BaseHTTPRequestHandler):
        def do_GET(self):  # noqa: N802
            payload = page_html.encode("utf-8")
            self.send_response(200)
            self.send_header("Content-Type", "text/html; charset=utf-8")
            self.send_header("Content-Length", str(len(payload)))
            self.end_headers()
            self.wfile.write(payload)
            served.set()

        def log_message(self, fmt, *args):  # noqa: A003
            return

    server = ThreadingHTTPServer(("127.0.0.1", 0), _StatusHandler)
    host, port = server.server_address
    fallback_url = f"http://{host}:{port}/?run_id={quote_plus(str(run_id))}"
    timeout_sec = max(0.5, float(os.environ.get("HIVE_TRACE_STATUS_PAGE_WAIT_SEC") or 1.5))

    def _serve():
        deadline = time.time() + timeout_sec
        server.timeout = 0.25
        try:
            while time.time() < deadline and not served.is_set():
                server.handle_request()
        finally:
            try:
                server.server_close()
            except Exception:
                pass

    thread = threading.Thread(target=_serve, daemon=True, name="hive-observe-status-page")
    thread.start()
    try:
        webbrowser.open(fallback_url, new=2)
    except Exception:
        pass
    thread.join(timeout=timeout_sec + 0.25)
    return fallback_url

