// Live API explorer — pick endpoint, see realistic JSON response.
const { useState: useState_a, useEffect: useEffect_a, useMemo: useMemo_a } = React;

const ENDPOINTS = [
  {
    id: "summary",
    method: "GET",
    path: "/v1/sg/summary",
    label: "/v1/sg/summary",
    desc: "Public network summary from the anonymised Singapore external view.",
    params: { view: "public-external", window: "1h" },
    response: () => ({
      scope: "sg-public-external",
      observed_at: "2026-05-06T16:10:00+08:00",
      streaming_clusters: 12,
      observation_cells: 24,
      activity_index: 82.4,
      signal_events_5m: 148,
      freshness_seconds: 38,
      series: [
        { ts: "2026-05-06T15:50:00+08:00", activity_index: 79.2 },
        { ts: "2026-05-06T15:55:00+08:00", activity_index: 80.8 },
        { ts: "2026-05-06T16:00:00+08:00", activity_index: 82.4 },
      ],
      note: "No portfolio totals, exact sites, or customer identifiers are included."
    }),
  },
  {
    id: "network",
    method: "GET",
    path: "/v1/sg/network",
    label: "/v1/sg/network",
    desc: "Clustered public network map with coarse geometry and anonymised labels.",
    params: { view: "public-external", density: "expanded" },
    response: () => ({
      scope: "sg-public-external",
      observed_at: "2026-05-06T16:10:00+08:00",
      projection: "coarse-cluster-grid",
      clusters: [
        {
          cluster_id: "SG-CENTRAL-07",
          label: "CENTRAL-07",
          lat: 1.291,
          lng: 103.851,
          activity_index: 84.1,
          status: "streaming",
          cells_reporting: 3,
          mix: ["solar", "battery", "weather"],
          delta_1h_pct: 4.8,
          freshness_seconds: 42,
        },
        {
          cluster_id: "SG-EAST-04",
          label: "EAST-04",
          lat: 1.321,
          lng: 103.932,
          activity_index: 76.3,
          status: "steady",
          cells_reporting: 2,
          mix: ["solar", "weather"],
          delta_1h_pct: -1.2,
          freshness_seconds: 35,
        },
      ],
      links: [
        { from: "SG-CENTRAL-07", to: "SG-EAST-04", flow_index: 0.62 },
      ],
      note: "Coordinates are coarse and cannot be used to infer exact asset locations.",
    }),
  },
  {
    id: "cluster",
    method: "GET",
    path: "/v1/sg/network/{cluster_id}",
    label: "/v1/sg/network/:cluster",
    desc: "Inspector detail for one anonymised public cluster.",
    params: { cluster_id: "SG-CENTRAL-07", window: "1h" },
    response: () => ({
      cluster_id: "SG-CENTRAL-07",
      label: "CENTRAL-07",
      observed_at: "2026-05-06T16:10:00+08:00",
      activity_index: 84.1,
      status: "streaming",
      cells_reporting: 3,
      mix: ["solar", "battery", "weather"],
      trend_1h: [
        { ts: "2026-05-06T15:50:00+08:00", activity_index: 80.2 },
        { ts: "2026-05-06T15:55:00+08:00", activity_index: 81.9 },
        { ts: "2026-05-06T16:00:00+08:00", activity_index: 84.1 },
      ],
      privacy: {
        exact_sites_exposed: false,
        customer_identifiers_exposed: false,
      },
    }),
  },
  {
    id: "series",
    method: "GET",
    path: "/v1/sg/network/series",
    label: "/v1/sg/network/series",
    desc: "Public time-series for network activity and freshness over the external map.",
    params: { window: "24h", bucket: "5m" },
    response: () => ({
      scope: "sg-public-external",
      bucket: "5m",
      series: [
        { ts: "2026-05-05T16:00:00+08:00", activity_index: 61.2, freshness_seconds: 46 },
        { ts: "2026-05-05T16:05:00+08:00", activity_index: 63.8, freshness_seconds: 41 },
        { ts: "2026-05-05T16:10:00+08:00", activity_index: 66.1, freshness_seconds: 39 },
      ],
      aggregate: {
        peak_activity_index: 88.7,
        median_freshness_seconds: 40,
      },
    }),
  },
  {
    id: "schema",
    method: "GET",
    path: "/v1/sg/schema",
    label: "/v1/sg/schema",
    desc: "Shape contract for the public external endpoints.",
    params: { version: "2026-05", surface: "public-external" },
    response: () => ({
      version: "2026-05",
      endpoints: ["/v1/sg/summary", "/v1/sg/network", "/v1/sg/network/{cluster_id}", "/v1/sg/network/series"],
      guarantees: {
        anonymised_clusters_only: true,
        exact_asset_locations: "excluded",
        portfolio_totals: "excluded",
        customer_names: "excluded",
      },
    }),
  },
];

function syntaxJson(obj, indent = 0) {
  // Render pretty JSON with span classes for syntax highlighting.
  const pad = (n) => " ".repeat(n);
  if (obj === null) return <span className="b">null</span>;
  if (typeof obj === "boolean") return <span className="b">{String(obj)}</span>;
  if (typeof obj === "number") return <span className="n">{obj}</span>;
  if (typeof obj === "string") return <span className="s">"{obj}"</span>;
  if (Array.isArray(obj)) {
    if (!obj.length) return <span><span className="p">[]</span></span>;
    return (
      <span>
        <span className="p">[</span>
        {obj.map((v, i) => (
          <div key={i} style={{ paddingLeft: (indent + 2) * 8 }}>
            {syntaxJson(v, indent + 2)}{i < obj.length - 1 ? <span className="p">,</span> : null}
          </div>
        ))}
        <div style={{ paddingLeft: indent * 8 }}><span className="p">]</span></div>
      </span>
    );
  }
  const keys = Object.keys(obj);
  return (
    <span>
      <span className="p">{"{"}</span>
      {keys.map((k, i) => (
        <div key={k} style={{ paddingLeft: (indent + 2) * 8 }}>
          <span className="k">"{k}"</span><span className="p">: </span>
          {syntaxJson(obj[k], indent + 2)}
          {i < keys.length - 1 ? <span className="p">,</span> : null}
        </div>
      ))}
      <div style={{ paddingLeft: indent * 8 }}><span className="p">{"}"}</span></div>
    </span>
  );
}

function APIExplorer({ accent }) {
  const [activeId, setActive] = useState_a("summary");
  const [data, setData] = useState_a(null);
  const [latency, setLatency] = useState_a(38);
  const [sending, setSending] = useState_a(false);

  const ep = ENDPOINTS.find(e => e.id === activeId);

  const send = () => {
    setSending(true);
    setData(null);
    const lat = 28 + Math.floor(Math.random() * 32);
    setLatency(lat);
    setTimeout(() => {
      setData(ep.response());
      setSending(false);
    }, lat + 80);
  };

  useEffect_a(() => { send(); /* eslint-disable-next-line */ }, [activeId]);

  const url = `https://graph.sg${ep.path}`;
  const qs = Object.entries(ep.params).map(([k, v]) => `${k}=${v}`).join("&");

  return (
    <section className="sec" id="developers" data-screen-label="developers">
      <div className="wrap">
        <div className="sec-head">
          <div className="label">07 · DEVELOPERS</div>
          <div>
            <h2>One public surface for the external network view.</h2>
            <p>The browser-facing API is intentionally narrow: anonymised cluster summaries, coarse geometry, freshness, and trend data. No portfolio totals, exact sites, or customer identifiers leave the protected layer.</p>
          </div>
        </div>

        <div className="api">
          <div className="api-side">
            <div className="api-side-head">
              <span>ENDPOINTS</span>
              <span style={{ color: "var(--accent)" }}>v1</span>
            </div>
            {ENDPOINTS.map(e => (
              <div key={e.id}
                   className={"api-endpoint" + (e.id === activeId ? " active" : "")}
                   onClick={() => setActive(e.id)}>
                <span className="method" style={{ color: e.method === "POST" ? "var(--warn)" : "var(--accent)" }}>{e.method}</span>
                <span style={{ flex: 1 }}>{e.label}</span>
              </div>
            ))}
            <div style={{ marginTop: "auto", padding: "16px 20px", borderTop: "1px solid var(--line)", fontFamily: "IBM Plex Mono, monospace", fontSize: 11, color: "var(--ink-3)" }}>
              <div>SURFACE · PUBLIC EXTERNAL</div>
              <div style={{ color: "var(--ink-2)", marginTop: 4 }}>read-only · anonymised · cacheable</div>
            </div>
          </div>

          <div className="api-main">
            <div className="api-bar">
              <span className="method" style={{ color: ep.method === "POST" ? "var(--warn)" : "var(--accent)", fontWeight: 600, fontSize: 12 }}>{ep.method}</span>
              <span className="url">
                <span className="host">https://graph.sg</span>
                <span className="path">{ep.path}</span>
                {qs ? <span className="q">?{qs}</span> : null}
              </span>
              <button className="api-send" onClick={send} disabled={sending}>
                {sending ? "RUNNING…" : "SEND ↵"}
              </button>
            </div>
            <div className="api-output">
              <div className="api-pane left">
                <h4>Request</h4>
                <div style={{ color: "var(--ink-3)" }}>
                  <div><span style={{ color: "var(--ink-2)" }}>{ep.method}</span> {ep.path}</div>
                  <div style={{ marginTop: 10, color: "var(--ink-3)" }}>Headers</div>
                  <div>  Accept: <span style={{ color: "var(--accent)" }}>"application/json"</span></div>
                  <div>  Cache-Control: <span style={{ color: "var(--accent)" }}>"max-age=30"</span></div>
                  <div style={{ marginTop: 10 }}>Params</div>
                  {Object.entries(ep.params).map(([k, v]) => (
                    <div key={k}>  {k}: <span style={{ color: "var(--accent)" }}>"{v}"</span></div>
                  ))}
                  <div style={{ marginTop: 14, color: "var(--ink-2)" }}>{ep.desc}</div>
                </div>
              </div>
              <div className="api-pane json">
                <h4>Response</h4>
                {sending ? (
                  <div style={{ color: "var(--ink-3)" }}>… streaming</div>
                ) : data ? syntaxJson(data) : null}
              </div>
            </div>
            <div className="api-status">
              <span className="ok">● 200 OK</span>
              <span>{latency} ms</span>
              <span>region: ap-southeast-1</span>
              <span style={{ marginLeft: "auto" }}>privacy: external-only</span>
            </div>
          </div>
        </div>

        <div style={{ marginTop: 20, display: "flex", gap: 14, alignItems: "center", flexWrap: "wrap" }}>
          <span className="mono" style={{ fontSize: 12, color: "var(--ink-3)", letterSpacing: "0.06em" }}>
            CLIENTS · CURL · PYTHON · NODE · GO
          </span>
          <span style={{ color: "var(--ink-4)" }}>·</span>
          <a href="#" className="mono" style={{ fontSize: 12, color: "var(--ink-2)" }}>READ THE DOCS →</a>
          <a href="#" className="mono" style={{ fontSize: 12, color: "var(--ink-2)" }}>POSTMAN COLLECTION ↗</a>
          <a href="#" className="mono" style={{ fontSize: 12, color: "var(--ink-2)" }}>OPENAPI 3.1 ↗</a>
        </div>
      </div>
    </section>
  );
}

window.APIExplorer = APIExplorer;
