// PURPOSE: Standalone demo of @crema/knowledge-ui over MockKnowledgeTransport.
//          Drop into a consuming app's route (e.g. routes/knowledge-demo.tsx) to
//          exercise every surface with fixtures and no running service.
// ===========================================================================
import { useEffect, useState } from "react";
import {
  ClaimsReviewQueue,
  CollectionForm,
  CollectionList,
  ExportPanel,
  ObjectList,
  ObjectViewer,
  MockKnowledgeTransport,
  type Claim,
  type Collection,
  type CollectionInput,
  type CollectionPatch,
  type ExportJob,
  type ExportScope,
  type KnowledgeTransport,
  type ObjectOutline,
  type ObjectSummary,
} from "../src/index";

const transport: KnowledgeTransport = new MockKnowledgeTransport();

type View =
  | { kind: "collections" }
  | { kind: "collection"; slug: string }
  | { kind: "object"; id: string };

export default function KnowledgeDemo() {
  const [tab, setTab] = useState<"browse" | "review" | "export">("browse");
  const [exports, setExports] = useState<ExportJob[]>([]);
  const [exportBusy, setExportBusy] = useState(false);
  const [view, setView] = useState<View>({ kind: "collections" });
  const [collections, setCollections] = useState<Collection[]>([]);
  const [pending, setPending] = useState<Record<string, number>>({});
  const [objects, setObjects] = useState<ObjectSummary[]>([]);
  const [outline, setOutline] = useState<ObjectOutline | null>(null);
  const [claims, setClaims] = useState<Claim[]>([]);
  const [busyId, setBusyId] = useState<string | undefined>();
  const [creating, setCreating] = useState<null | "account" | "tenant">(null);
  const [editing, setEditing] = useState<Collection | null>(null);
  const [busy, setBusy] = useState(false);

  async function refresh() {
    const page = await transport.listCollections();
    setCollections(page.collections);
    const queue = await transport.reviewQueue();
    setClaims(queue);
    const counts: Record<string, number> = {};
    for (const c of queue) counts[c.collection] = (counts[c.collection] ?? 0) + 1;
    setPending(counts);
  }

  async function afterClaim(id: string, fn: () => Promise<unknown>) {
    setBusyId(id);
    await fn();
    setBusyId(undefined);
    void refresh();
  }

  // App-side polling of in-flight exports (the timer lives here, not in the lib).
  async function requestExport(scope: ExportScope) {
    setExportBusy(true);
    const job = await transport.createExport(scope);
    setExports((prev) => [job, ...prev]);
    setExportBusy(false);
    poll(job.id);
  }
  function poll(id: string) {
    const tick = async () => {
      const job = await transport.getExport(id);
      setExports((prev) => prev.map((e) => (e.id === id ? job : e)));
      if (job.status === "pending" || job.status === "running") setTimeout(tick, 1500);
    };
    setTimeout(tick, 800);
  }

  useEffect(() => {
    void refresh();
  }, []);

  useEffect(() => {
    if (view.kind === "collection") void transport.listObjects(view.slug).then((p) => setObjects(p.objects));
    if (view.kind === "object") void transport.outline(view.id).then(setOutline);
  }, [view]);

  async function onCreate(value: CollectionInput | CollectionPatch) {
    setBusy(true);
    await transport.createCollection(value as CollectionInput);
    setBusy(false);
    setCreating(null);
    void refresh();
  }
  async function onEdit(value: CollectionInput | CollectionPatch) {
    if (!editing) return;
    setBusy(true);
    await transport.updateCollection(editing.slug, value as CollectionPatch);
    setBusy(false);
    setEditing(null);
    void refresh();
  }

  const reviewCount = claims.length;

  return (
    <div className="mx-auto max-w-5xl p-6">
      <div className="mb-4 flex items-center gap-2">
        <TabBtn active={tab === "browse"} onClick={() => setTab("browse")}>Browse</TabBtn>
        <TabBtn active={tab === "review"} onClick={() => setTab("review")}>
          Review{reviewCount > 0 ? ` (${reviewCount})` : ""}
        </TabBtn>
        <TabBtn active={tab === "export"} onClick={() => setTab("export")}>Export</TabBtn>
      </div>

      {tab === "export" && (
        <ExportPanel
          collections={collections}
          jobs={exports}
          busy={exportBusy}
          onRequest={requestExport}
          onDownload={(job) => job.download_url && window.open(job.download_url)}
        />
      )}

      {tab === "review" && (
        <ClaimsReviewQueue
          claims={claims}
          busyId={busyId}
          onConfirm={(id) => afterClaim(id, () => transport.confirmClaim(id))}
          onReject={(id) => afterClaim(id, () => transport.rejectClaim(id))}
          onKeep={(winner, supersede) => afterClaim(winner, () => transport.confirmClaim(winner, { supersede }))}
          onDismissConflict={(id) => afterClaim(id, () => transport.dismissConflict(id))}
          onOpenSource={(objectId) => {
            setTab("browse");
            setView({ kind: "object", id: objectId });
          }}
        />
      )}

      {tab === "browse" && view.kind !== "collections" && (
        <button
          type="button"
          onClick={() => setView({ kind: "collections" })}
          className="mb-4 text-sm text-muted-foreground hover:text-foreground"
        >
          ← All corpuses
        </button>
      )}

      {tab === "browse" && view.kind === "collections" && (
        <>
          {creating && (
            <div className="mb-6 rounded-xl border border-border bg-card p-4">
              <h2 className="mb-3 font-medium">New corpus</h2>
              <CollectionForm mode="create" ownerType={creating} orgName="Acme" canManageTenant busy={busy} onSubmit={onCreate} onCancel={() => setCreating(null)} />
            </div>
          )}
          {editing && (
            <div className="mb-6 rounded-xl border border-border bg-card p-4">
              <h2 className="mb-3 font-medium">Corpus settings</h2>
              <CollectionForm mode="edit" initial={editing} orgName="Acme" canManageTenant busy={busy} onSubmit={onEdit} onCancel={() => setEditing(null)} />
            </div>
          )}
          <CollectionList
            collections={collections}
            pendingCounts={pending}
            orgName="Acme"
            canManageTenant
            onCreate={(owner) => setCreating(owner)}
            onOpen={(c) => setView({ kind: "collection", slug: c.slug })}
          />
        </>
      )}

      {tab === "browse" && view.kind === "collection" && (
        <>
          <div className="mb-3 flex items-center justify-between">
            <h1 className="text-lg font-semibold">{view.slug}</h1>
            <button className="text-sm text-primary" onClick={() => setEditing(collections.find((c) => c.slug === view.slug) ?? null)}>Settings</button>
          </div>
          <ObjectList objects={objects} onOpen={(o) => setView({ kind: "object", id: o.object_id })} />
        </>
      )}

      {tab === "browse" && view.kind === "object" && outline && (
        <ObjectViewer
          outline={outline}
          readText={(sel) => transport.readText(outline.object_id, sel)}
          resolveBlobUrl={() => transport.blobUrl(outline.object_id)}
          onOpenObject={(id) => setView({ kind: "object", id })}
          actions={{
            onVerify: () => transport.updateObject(outline.object_id, { verified_at: new Date().toISOString() }),
            onDownload: () => transport.blobUrl(outline.object_id).then((u) => window.open(u)),
          }}
        />
      )}
    </div>
  );
}

function TabBtn({ active, onClick, children }: { active: boolean; onClick: () => void; children: React.ReactNode }) {
  return (
    <button
      type="button"
      onClick={onClick}
      className={
        "rounded-lg px-3 py-1.5 text-sm font-medium transition " +
        (active ? "bg-primary/10 text-primary" : "text-muted-foreground hover:bg-muted")
      }
    >
      {children}
    </button>
  );
}
