import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useTranslation } from "react-i18next";
import { CheckCircle2, Clock, Database, History, Loader2, Pause, Play } from "lucide-react";
import { api, type MyStatus } from "../lib/api";
import { formatViews } from "../lib/format";
import Tooltip from "./Tooltip";
// Per-user status (not the global catalog): shows the number of videos available to *this*
// user, how many of *their* channels are still being fetched, and how many lack full
// history (clickable -> channel manager filtered to those). The pause control is admin-only.
export default function SyncStatus({
isAdmin,
onGoToFullHistory,
variant = "bar",
collapsed = false,
}: {
isAdmin: boolean;
onGoToFullHistory: () => void;
// "bar" = the legacy horizontal top-bar row. "rail" = a compact block for the top of the
// left nav sidebar (stacked; icon-only with a tooltip when the rail is collapsed).
variant?: "bar" | "rail";
collapsed?: boolean;
}) {
const { t } = useTranslation();
const qc = useQueryClient();
const { data } = useQuery({
queryKey: ["my-status"],
queryFn: api.myStatus,
// Track the scheduler near-real-time: poll even when the tab is backgrounded, and
// refresh immediately on tab focus (the global default disables focus refetch), so the
// "N without full history" count keeps ticking down without a manual reload. Poll faster
// while a job is running or work is pending — so the live "syncing" state is actually
// caught — and ease back to a slow idle tick once everything's settled.
refetchInterval: (query) => {
const d = query.state.data as MyStatus | undefined;
const busy =
!!d &&
(d.sync_active || d.channels_recent_pending > 0 || d.channels_deep_pending > 0);
return busy ? 8_000 : 30_000;
},
refetchIntervalInBackground: true,
refetchOnWindowFocus: true,
staleTime: 5_000,
});
const toggle = useMutation({
mutationFn: () => (data?.paused ? api.resumeSync() : api.pauseSync()),
onSuccess: () => qc.invalidateQueries({ queryKey: ["my-status"] }),
});
if (!data) return null;
const syncing = data.channels_recent_pending;
const notFull = data.channels_deep_pending; // your channels without full history yet
// Spin only while a sync job is actually running; otherwise pending work shows as a calm,
// static state (or, for deep history, just the "N without full history" link below).
const active = data.sync_active;
const showMain = data.paused || active || syncing > 0 || notFull === 0;
// Calm one-liner describing the current sync state; shared by the bar and rail layouts.
const stateNode = data.paused ? (
{t("header.sync.paused")}
) : active ? (