import { useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";
import { useQuery } from "@tanstack/react-query";
import { listPublicationPoints } from "../api/service";
import type { PublicationPointRecord } from "../api/schemas";
import { CursorPagerControls } from "../components/CursorPagerControls";
import { DataTable, type Column } from "../components/DataTable";
import { PageHeader } from "../components/PageHeader";
import { Panel } from "../components/Panel";
import { StatusPill } from "../components/StatusPill";
import { useCursorPager } from "../lib/cursor";
import { formatDurationMs, formatInt, truncateMiddle } from "../lib/format";
import { withRunParam } from "../lib/run";
import { useRun } from "../lib/useRun";

export default function PublicationPointsPage() {
  const { runId } = useRun();
  const navigate = useNavigate();
  const pager = useCursorPager(runId);
  const [needle, setNeedle] = useState("");

  const ppsQuery = useQuery({
    queryKey: ["pps", runId, pager.cursor],
    queryFn: () => listPublicationPoints(runId, { limit: 50, cursor: pager.cursor }),
    placeholderData: (prev) => prev,
  });

  const rows = useMemo(() => {
    const items = ppsQuery.data?.items ?? [];
    const q = needle.trim().toLowerCase();
    if (!q) return items;
    return items.filter((pp) =>
      [pp.manifestRsyncUri, pp.publicationPointRsyncUri, pp.rrdpNotificationUri, pp.rsyncBaseUri, pp.ppId]
        .filter(Boolean)
        .some((value) => value!.toLowerCase().includes(q)),
    );
  }, [ppsQuery.data, needle]);

  const columns: Column<PublicationPointRecord>[] = [
    {
      key: "manifest",
      header: "Publication point",
      render: (pp) => (
        <div>
          <div className="cell-main mono text-small ellipsis" style={{ maxWidth: 380 }} title={pp.manifestRsyncUri ?? pp.ppId}>
            {pp.manifestRsyncUri ? truncateMiddle(pp.manifestRsyncUri, 68) : pp.ppId}
          </div>
          <div className="text-faint text-small mono">{pp.ppId}</div>
        </div>
      ),
    },
    {
      key: "source",
      header: "Sync source",
      render: (pp) => <span className="chip">{pp.repoSyncSource ?? pp.source ?? "—"}</span>,
    },
    {
      key: "state",
      header: "Terminal state",
      render: (pp) => <StatusPill status={pp.repoTerminalState} />,
    },
    { key: "objects", header: "Objects", numeric: true, render: (pp) => formatInt(pp.objects) },
    {
      key: "rejected",
      header: "Rejected",
      numeric: true,
      render: (pp) =>
        pp.rejectedObjects ? (
          <span style={{ color: "var(--red-700)", fontWeight: 600 }}>{formatInt(pp.rejectedObjects)}</span>
        ) : (
          "0"
        ),
    },
    { key: "warnings", header: "Warnings", numeric: true, render: (pp) => formatInt(pp.warnings) },
    {
      key: "duration",
      header: "Sync time",
      numeric: true,
      render: (pp) => formatDurationMs(pp.repoSyncDurationMs),
    },
  ];

  return (
    <div className="page">
      <PageHeader title="Publication Points" subtitle="All publication points indexed for the active run" />
      <Panel
        title="All publication points"
        tools={
          <input
            type="search"
            value={needle}
            onChange={(e) => setNeedle(e.target.value)}
            placeholder="Filter current page (URI/id)…"
            aria-label="Filter current page"
            style={{ minWidth: 220, padding: "5px 8px", border: "1px solid var(--border)", borderRadius: "var(--radius-m)" }}
          />
        }
        flush
      >
        <DataTable
          columns={columns}
          rows={rows}
          rowKey={(pp) => pp.ppId}
          loading={ppsQuery.isPending}
          error={ppsQuery.isError ? ppsQuery.error : undefined}
          onRetry={() => ppsQuery.refetch()}
          emptyTitle={needle.trim() ? "No matches on this page — clear the filter" : "No publication points indexed"}
          emptyHint={needle.trim() ? "The filter only narrows the rows of the current page." : undefined}
          caption="Publication points"
          onRowClick={(pp) =>
            navigate(withRunParam(`/publication-points/${encodeURIComponent(pp.ppId)}`, runId))
          }
        />
        <CursorPagerControls
          page={pager.page}
          canPrev={pager.canPrev}
          hasNext={ppsQuery.data?.nextCursor != null}
          loading={ppsQuery.isFetching}
          onPrev={pager.goPrev}
          onNext={() => pager.goNext(ppsQuery.data?.nextCursor ?? null)}
          itemCount={rows.length}
        />
      </Panel>
    </div>
  );
}
