/**
 * `useBans` hook.
 *
 * Fetches and manages paginated ban-list data from the dashboard endpoint.
 * Re-fetches automatically when `timeRange`, `page`, `origin`, or `source` changes.
 */

import { useCallback, useState } from "react";
import { fetchBans } from "../api/dashboard";
import { useListData } from "./useListData";
import { BAN_PAGE_SIZE } from "../utils/constants";
import type { DashboardBanItem, TimeRange, BanOriginFilter, DashboardBanListResponse } from "../types/ban";
import type { FetchError } from "../types/api";

/** Return value shape for {@link useBans}. */
export interface UseBansResult {
  /** Ban items for the current page. */
  banItems: DashboardBanItem[];
  /** Total records in the selected time window (for pagination). */
  total: number;
  /** Current 1-based page number. */
  page: number;
  /** Navigate to a specific page. */
  setPage: (p: number) => void;
  /** Whether a fetch is currently in flight. */
  loading: boolean;
  /** Error message if the last fetch failed, otherwise `null`. */
  error: FetchError | null;
  /** Imperatively re-fetch the current page. */
  refresh: () => void;
}

/**
 * Fetch and manage dashboard ban-list data.
 *
 * Automatically re-fetches when `timeRange`, `origin`, `page`, or `source` changes.
 *
 * @param timeRange - Time-range preset that controls how far back to look.
 * @param origin    - Origin filter (default `"all"`).
 * @param source    - Data source: `"fail2ban"` (live) or `"archive"` (historical).
 * @returns Current data, pagination state, loading flag, and a `refresh` callback.
 */
export function useBans(
  timeRange: TimeRange,
  origin: BanOriginFilter = "all",
  source: "fail2ban" | "archive" = "fail2ban",
): UseBansResult {
  const [page, setPage] = useState<number>(1);
  const [total, setTotal] = useState<number>(0);

  const fetcher = useCallback(
    (signal: AbortSignal) => fetchBans(timeRange, page, BAN_PAGE_SIZE, origin, source, signal),
    [timeRange, page, origin, source],
  );

  const selector = useCallback((response: DashboardBanListResponse) => response.items, []);

  const onSuccess = useCallback((response: DashboardBanListResponse) => {
    setTotal(response.total);
  }, []);

  const { items: banItems, loading, error, refresh } = useListData<DashboardBanListResponse, DashboardBanItem>({
    fetcher,
    selector,
    errorMessage: "Failed to fetch bans",
    onSuccess,
  });

  return {
    banItems,
    total,
    page,
    setPage,
    loading,
    error,
    refresh,
  };
}
