/**
 * React hook for live active ban list management.
 */

import { useCallback } from "react";
import { banIp, fetchActiveBans, unbanAllBans, unbanIp } from "../api/jails";
import { useListData } from "./useListData";
import type { ActiveBan, UnbanAllResponse, ActiveBanListResponse } from "../types/jail";
import type { FetchError } from "../types/api";

export interface UseActiveBansResult {
  bans: ActiveBan[];
  total: number;
  loading: boolean;
  error: FetchError | null;
  refresh: () => void;
  banIp: (jail: string, ip: string) => Promise<void>;
  unbanIp: (ip: string, jail?: string) => Promise<void>;
  unbanAll: () => Promise<UnbanAllResponse>;
}

/**
 * Fetch and manage the currently-active ban list.
 *
 * Provides operations to ban, unban, and refresh the active ban list.
 * Automatically re-fetches after state-mutating operations.
 *
 * @returns Active ban list, loading/error states, and action callbacks.
 */
export function useActiveBans(): UseActiveBansResult {
  const fetcher = useCallback((signal: AbortSignal) => fetchActiveBans(signal), []);

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

  const { items: bans, loading, error, refresh } = useListData<ActiveBanListResponse, ActiveBan>({
    fetcher,
    selector,
    errorMessage: "Failed to fetch active bans",
  });

  const doBan = useCallback(
    async (jail: string, ip: string): Promise<void> => {
      await banIp(jail, ip);
      refresh();
    },
    [refresh],
  );

  const doUnban = useCallback(
    async (ip: string, jail?: string): Promise<void> => {
      await unbanIp(ip, jail);
      refresh();
    },
    [refresh],
  );

  const doUnbanAll = useCallback(
    async (): Promise<UnbanAllResponse> => {
      const result = await unbanAllBans();
      refresh();
      return result;
    },
    [refresh],
  );

  return {
    bans,
    total: bans.length,
    loading,
    error,
    refresh,
    banIp: doBan,
    unbanIp: doUnban,
    unbanAll: doUnbanAll,
  };
}
