import { useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";
import { useQuery } from "@tanstack/react-query";
import { listRepos } from "../api/service";
import type { RepositoryRecord } 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 { formatBytes, formatDurationMs, formatInt, truncateMiddle } from "../lib/format";
import { withRunParam } from "../lib/run";
import { useRun } from "../lib/useRun";

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

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

  const rows = useMemo(() => {
    const items = reposQuery.data?.items ?? [];
    const q = needle.trim().toLowerCase();
    if (!q) return items;
    return items.filter(
      (repo) =>
        repo.host.toLowerCase().includes(q) || repo.uri.toLowerCase().includes(q),
    );
  }, [reposQuery.data, needle]);

  const columns: Column<RepositoryRecord>[] = [
    {
      key: "host",
      header: "Repository",
      render: (repo) => (
        <div>
          <div className="cell-main">{repo.host}</div>
          <div className="text-faint text-small mono ellipsis" style={{ maxWidth: 320 }} title={repo.uri}>
            {truncateMiddle(repo.uri, 64)}
          </div>
        </div>
      ),
    },
    {
      key: "transport",
      header: "Transport",
      render: (repo) => <span className="chip">{repo.transport ?? "unknown"}</span>,
    },
    { key: "pps", header: "PPs", numeric: true, render: (repo) => formatInt(repo.publicationPoints) },
    { key: "objects", header: "Objects", numeric: true, render: (repo) => formatInt(repo.objects) },
    {
      key: "rejected",
      header: "Rejected",
      numeric: true,
      render: (repo) =>
        repo.rejectedObjects ? (
          <span style={{ color: "var(--red-700)", fontWeight: 600 }}>{formatInt(repo.rejectedObjects)}</span>
        ) : (
          "0"
        ),
    },
    { key: "bytes", header: "Downloaded", numeric: true, render: (repo) => formatBytes(repo.downloadBytes) },
    {
      key: "duration",
      header: "Sync time",
      numeric: true,
      render: (repo) => formatDurationMs(repo.syncDurationMsTotal),
    },
    {
      key: "terminal",
      header: "Terminal states",
      render: (repo) => (
        <span className="chip-list">
          {Object.entries(repo.terminalStates ?? {}).map(([state, count]) => (
            <StatusPill key={state} status={state} label={`${state} ${formatInt(count)}`} />
          ))}
        </span>
      ),
    },
  ];

  return (
    <div className="page">
      <PageHeader
        title="Repositories"
        subtitle={
          runQuery.data
            ? `${formatInt(runQuery.data.counts?.objects)} objects across all repositories in ${runQuery.data.runId}`
            : undefined
        }
      />
      <Panel
        title="All repositories"
        tools={
          <div className="filter-field">
            <label htmlFor="repo-filter" className="sr-only">
              Filter current page
            </label>
            <input
              id="repo-filter"
              type="search"
              value={needle}
              onChange={(e) => setNeedle(e.target.value)}
              placeholder="Filter current page (host/URI)…"
              style={{ minWidth: 220 }}
            />
          </div>
        }
        flush
      >
        <DataTable
          columns={columns}
          rows={rows}
          rowKey={(repo) => repo.repoId}
          loading={reposQuery.isPending}
          error={reposQuery.isError ? reposQuery.error : undefined}
          onRetry={() => reposQuery.refetch()}
          emptyTitle={needle.trim() ? "No matches on this page — clear the filter" : "No repositories indexed"}
          emptyHint={
            needle.trim()
              ? "The filter only narrows the rows of the current page."
              : "The query service has not indexed any run yet."
          }
          caption="Repositories"
          onRowClick={(repo) =>
            navigate(withRunParam(`/repositories/${encodeURIComponent(repo.repoId)}`, runId))
          }
        />
        <CursorPagerControls
          page={pager.page}
          canPrev={pager.canPrev}
          hasNext={reposQuery.data?.nextCursor != null}
          loading={reposQuery.isFetching}
          onPrev={pager.goPrev}
          onNext={() => pager.goNext(reposQuery.data?.nextCursor ?? null)}
          itemCount={rows.length}
        />
      </Panel>
    </div>
  );
}
