import { useQuery } from "@tanstack/react-query";
import { getHealth, getServiceInfo } from "../api/service";
import { CopyableValue } from "../components/CopyableValue";
import { PageHeader } from "../components/PageHeader";
import { Panel } from "../components/Panel";
import { StatusPill } from "../components/StatusPill";
import { ErrorBlock } from "../components/StateBlock";
import { useRun } from "../lib/useRun";

const ENDPOINTS: { method: "GET" | "POST"; path: string; note: string }[] = [
  { method: "GET", path: "/api/v1/healthz", note: "Service health + latest indexed run" },
  { method: "GET", path: "/api/v1/runs", note: "Run history (cursor paged)" },
  { method: "GET", path: "/api/v1/runs/{run}", note: "Run record ('latest' accepted)" },
  { method: "GET", path: "/api/v1/runs/{run}/repos", note: "Repositories (cursor paged)" },
  { method: "GET", path: "/api/v1/runs/{run}/repos/{id}/publication-points", note: "PPs of a repository" },
  { method: "GET", path: "/api/v1/runs/{run}/publication-points/{id}/objects", note: "Objects of a PP (filters: type,result,rejected,reason,q)" },
  { method: "GET", path: "/api/v1/runs/{run}/objects", note: "All objects (streamed; same filters)" },
  { method: "GET", path: "/api/v1/runs/{run}/objects/by-uri?uri=", note: "Exact URI lookup" },
  { method: "GET", path: "/api/v1/runs/{run}/objects/{id}/parsed", note: "Parsed projection (needs repo-bytes-db)" },
  { method: "GET", path: "/api/v1/runs/{run}/objects/{id}/validation", note: "Validation summary" },
  { method: "GET", path: "/api/v1/runs/{run}/objects/{id}/chain", note: "Chain edges" },
  { method: "GET", path: "/api/v1/runs/{run}/objects/{id}/raw", note: "Raw DER bytes (needs repo-bytes-db)" },
  { method: "GET", path: "/api/v1/runs/{run}/issues", note: "Rejected/errored objects (filters: reason,type,repoId,ppId)" },
  { method: "GET", path: "/api/v1/runs/{run}/search?q=", note: "Unified search: URI / sha256 / repo host / PP URI" },
  { method: "GET", path: "/api/v1/runs/{run}/vrps/lookup?ip=|prefix=[&asn=]", note: "VRP lookup (covering semantics, cursor paged)" },
  { method: "GET", path: "/api/v1/runs/{run}/stats/{validation,object-types,reasons}", note: "Aggregated counters" },
  { method: "POST", path: "/api/v1/runs/{run}/exports", note: "Start export job (repo / publication_point / object_set)" },
  { method: "GET", path: "/api/v1/runs/{run}/exports", note: "Export job list (process memory)" },
  { method: "GET", path: "/api/v1/runs/{run}/exports/{job}/download", note: "Download export tarball" },
  { method: "POST", path: "/api/v1/runs/{run}/objects/{id}/validation/explain", note: "On-demand validation explain (audit projection)" },
];

export default function ApiStatusPage() {
  const { runId, runQuery } = useRun();
  const infoQuery = useQuery({ queryKey: ["service-info"], queryFn: getServiceInfo });
  const healthQuery = useQuery({ queryKey: ["health"], queryFn: getHealth });

  return (
    <div className="page">
      <PageHeader title="API" subtitle="Query service connection status and endpoint reference" />

      <div className="detail-grid">
        <Panel title="Service">
          {infoQuery.isError ? (
            <ErrorBlock error={infoQuery.error} onRetry={() => infoQuery.refetch()} title="Query service unreachable" />
          ) : (
            <dl className="meta-grid">
              <dt>Service</dt>
              <dd className="mono">{infoQuery.data?.service ?? "…"}</dd>
              <dt>API version</dt>
              <dd className="mono">{infoQuery.data?.version ?? "…"}</dd>
              <dt>Health</dt>
              <dd>
                {healthQuery.isError ? (
                  <StatusPill status="error" label="unhealthy" />
                ) : (
                  <StatusPill status={healthQuery.data?.status ?? "unknown"} />
                )}
              </dd>
              <dt>Latest indexed run</dt>
              <dd className="mono">{healthQuery.data?.latestReadyRun ?? "—"}</dd>
            </dl>
          )}
        </Panel>

        <Panel title="Explorer context">
          <dl className="meta-grid">
            <dt>Active run</dt>
            <dd className="mono">{runQuery.data?.runId ?? runId}</dd>
            <dt>Index status</dt>
            <dd><StatusPill status={runQuery.data?.indexStatus} /></dd>
            <dt>API base</dt>
            <dd><CopyableValue value={`${window.location.origin}/api/v1`} max={64} label="API base URL" /></dd>
          </dl>
        </Panel>
      </div>

      <Panel title="Deployment notes">
        <ul style={{ margin: 0, paddingLeft: 18, display: "flex", flexDirection: "column", gap: 6 }}>
          <li>The query service has no CORS headers and no authentication — always front it with a same-origin proxy (this SPA) or an API gateway.</li>
          <li><code>/parsed</code>, <code>/raw</code> and exports require <code>--repo-bytes-db</code>.</li>
          <li>All list endpoints paginate with <code>limit</code> + <code>cursor</code>; the envelope is <code>{"{data, page, meta}"}</code>.</li>
        </ul>
      </Panel>

      <Panel title="Endpoint reference" flush>
        <div className="table-wrap">
          <table className="data-table endpoint-table">
            <thead>
              <tr>
                <th scope="col">Endpoint</th>
                <th scope="col">Purpose</th>
              </tr>
            </thead>
            <tbody>
              {ENDPOINTS.map((endpoint) => (
                <tr key={`${endpoint.method}:${endpoint.path}`}>
                  <td>
                    <span className={`method${endpoint.method === "POST" ? " post" : ""}`}>{endpoint.method}</span>
                    {endpoint.path}
                  </td>
                  <td>{endpoint.note}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </Panel>
    </div>
  );
}
