import { useQuery } from "@tanstack/react-query";
import { exportDownloadUrl, listExports } from "../api/service";
import type { ExportJobRecord } from "../api/schemas";
import { DataTable, type Column } from "../components/DataTable";
import { PageHeader } from "../components/PageHeader";
import { Panel } from "../components/Panel";
import { StatusPill } from "../components/StatusPill";
import { ErrorBlock, Notice } from "../components/StateBlock";
import { formatBytes, formatInt, formatRelative, formatUtc } from "../lib/format";
import { useRun, runErrorTitle } from "../lib/useRun";

/**
 * Export job history for the active run. Jobs are held in the query service
 * process memory, so the list resets when the service restarts.
 */
export default function ExportsPage() {
  const { runId, runQuery } = useRun();

  const exportsQuery = useQuery({
    queryKey: ["exports", runId],
    queryFn: () => listExports(runId, { limit: 50 }),
    refetchInterval: (query) => {
      const jobs = query.state.data?.items ?? [];
      return jobs.some((job) => job.status === "running") ? 2000 : false;
    },
  });

  if (runQuery.isError) {
    return (
      <div className="page">
        <PageHeader title="Exports" />
        <ErrorBlock
          error={runQuery.error}
          onRetry={() => runQuery.refetch()}
          title={runErrorTitle(runId, runQuery.error)}
        />
      </div>
    );
  }

  const columns: Column<ExportJobRecord>[] = [
    {
      key: "job",
      header: "Job",
      render: (job) => <span className="mono text-small">{job.jobId.slice(0, 12)}…</span>,
    },
    { key: "scope", header: "Scope", render: (job) => <span className="chip">{job.scope}</span> },
    {
      key: "target",
      header: "Target",
      render: (job) => (
        <span className="mono text-small">{job.repoId ?? job.ppId ?? "object set"}</span>
      ),
    },
    { key: "status", header: "Status", render: (job) => <StatusPill status={job.status} /> },
    {
      key: "objects",
      header: "Objects",
      numeric: true,
      render: (job) => formatInt(job.objectCount),
    },
    { key: "bytes", header: "Size", numeric: true, render: (job) => formatBytes(job.bytesWritten) },
    {
      key: "created",
      header: "Created",
      render: (job) => <span title={formatUtc(job.createdAt)}>{formatRelative(job.createdAt)}</span>,
    },
    {
      key: "error",
      header: "Error",
      render: (job) =>
        job.error ? <span className="text-small" title={job.error}>{job.error}</span> : <span className="text-faint">—</span>,
    },
    {
      key: "download",
      header: "",
      render: (job) =>
        job.status === "complete" ? (
          <a className="btn small primary" href={exportDownloadUrl(runId, job.jobId)} download>
            Download
          </a>
        ) : null,
    },
  ];

  return (
    <div className="page">
      <PageHeader
        title="Exports"
        subtitle="Evidence bundles (raw object tarballs) produced by the query service"
      />
      <Notice kind="info">
        Export jobs live in the query service process memory and are cleared on
        restart. Creating exports requires the service to run with --repo-bytes-db.
        New exports can be started from an object, publication point or repository
        page.
      </Notice>
      <Panel title="Jobs" flush>
        <DataTable
          columns={columns}
          rows={exportsQuery.data?.items ?? []}
          rowKey={(job) => job.jobId}
          loading={exportsQuery.isPending}
          error={exportsQuery.isError ? exportsQuery.error : undefined}
          onRetry={() => exportsQuery.refetch()}
          emptyTitle="No export jobs yet"
          emptyHint="Start an export from an object detail page (object set) to see it here."
          caption="Export jobs"
        />
      </Panel>
    </div>
  );
}
