// PURPOSE: Export bundle flow (spec §3.4, §8). Request an export of the whole
//          estate or one corpus; the app polls getExport and feeds jobs back in
//          (the timer lives in the app, per the polling contract). Download on
//          ready, error verbatim on failure. Props in, callbacks out.
// ===========================================================================
import { useState, type FC, type ReactNode } from "react";
import { Archive, CheckCircle2, Download, Loader2, XCircle } from "lucide-react";
import type { Collection, ExportJob, ExportScope } from "./types";
import { Spinner, cn, formatBytes, formatRelative } from "./_internal";

// ---- ExportJobRow ---------------------------------------------------------

export const ExportJobRow: FC<{ job: ExportJob; onDownload?: (job: ExportJob) => void; className?: string }> = ({
  job,
  onDownload,
  className,
}) => {
  const running = job.status === "pending" || job.status === "running";
  return (
    <div className={cn("flex items-center gap-3 rounded-lg border border-border bg-card px-4 py-3", className)}>
      <StatusIcon status={job.status} />
      <div className="min-w-0 flex-1">
        <p className="truncate text-sm font-medium text-foreground">
          {job.scope === "all" ? "Whole knowledge base" : job.scope}
        </p>
        <p className="text-xs text-muted-foreground">
          {running
            ? "Building…"
            : job.status === "ready"
              ? `${job.object_count ?? 0} items · ${formatBytes(job.byte_size)} · ${formatRelative(job.updated_at)}`
              : job.error || "Failed"}
        </p>
      </div>
      {job.status === "ready" && onDownload && (
        <button
          type="button"
          data-action="knowledge-export-download"
          onClick={() => onDownload(job)}
          className="inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground transition hover:opacity-90"
        >
          <Download className="size-3.5" /> Download
        </button>
      )}
      {running && <Spinner />}
    </div>
  );
};

const StatusIcon: FC<{ status: ExportJob["status"] }> = ({ status }) => {
  if (status === "ready") return <CheckCircle2 className="size-5 text-[var(--success)]" />;
  if (status === "failed") return <XCircle className="size-5 text-destructive" />;
  return <Archive className="size-5 text-muted-foreground" />;
};

// ---- ExportPanel ----------------------------------------------------------

export interface ExportPanelProps {
  /** Corpuses the caller may export (for the scope picker). */
  collections: Collection[];
  jobs: ExportJob[];
  busy?: boolean;
  onRequest: (scope: ExportScope) => void;
  onDownload?: (job: ExportJob) => void;
  intro?: ReactNode;
  className?: string;
}

export const ExportPanel: FC<ExportPanelProps> = ({ collections, jobs, busy, onRequest, onDownload, intro, className }) => {
  const [scope, setScope] = useState<ExportScope>("all");

  return (
    <div className={cn("flex flex-col gap-6", className)}>
      <div className="rounded-xl border border-border bg-card p-4">
        <h2 className="text-sm font-semibold text-foreground">Export a bundle</h2>
        <p className="mt-1 text-sm text-muted-foreground">
          {intro ?? (
            <>
              A self-contained zip — your originals, extracted text, catalog cards, and claims, in open formats.
              Citations resolve inside the bundle, so it stays readable with no service in the loop. It's yours to keep.
            </>
          )}
        </p>
        <div className="mt-4 flex flex-wrap items-end gap-3">
          <label className="flex flex-col gap-1.5">
            <span className="text-xs font-medium text-muted-foreground">Scope</span>
            <select
              data-action="knowledge-export-scope"
              className="rounded-lg border border-border bg-background px-3 py-2 text-sm outline-none focus:border-primary/50 focus:ring-2 focus:ring-primary/30"
              value={scope}
              onChange={(e) => setScope(e.target.value)}
            >
              <option value="all">Whole knowledge base</option>
              {collections.map((c) => (
                <option key={c.slug} value={c.slug}>
                  {c.name}
                </option>
              ))}
            </select>
          </label>
          <button
            type="button"
            data-action="knowledge-export-request"
            disabled={busy}
            onClick={() => onRequest(scope)}
            className="inline-flex items-center gap-2 rounded-lg bg-primary px-4 py-2 text-sm font-medium text-primary-foreground transition hover:opacity-90 disabled:opacity-50"
          >
            {busy ? <Loader2 className="size-4 animate-spin" /> : <Archive className="size-4" />}
            Request export
          </button>
        </div>
      </div>

      {jobs.length > 0 && (
        <div className="flex flex-col gap-2">
          <h3 className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">Exports</h3>
          {jobs.map((j) => (
            <ExportJobRow key={j.id} job={j} onDownload={onDownload} />
          ))}
        </div>
      )}
    </div>
  );
};
