/**
 * React hook for listing and mutating blocklist sources.
 */

import { useCallback } from "react";
import {
  createBlocklist,
  deleteBlocklist,
  fetchBlocklists,
  previewBlocklist,
  updateBlocklist,
} from "../api/blocklist";
import { useListData } from "./useListData";
import type {
  BlocklistSource,
  BlocklistSourceCreate,
  BlocklistSourceUpdate,
  BlocklistListResponse,
  PreviewResponse,
} from "../types/blocklist";
import type { FetchError } from "../types/api";

export interface UseBlocklistsReturn {
  sources: BlocklistSource[];
  loading: boolean;
  error: FetchError | null;
  refresh: () => void;
  createSource: (payload: BlocklistSourceCreate) => Promise<BlocklistSource>;
  updateSource: (id: number, payload: BlocklistSourceUpdate) => Promise<BlocklistSource>;
  removeSource: (id: number) => Promise<void>;
  previewSource: (id: number) => Promise<PreviewResponse>;
}

/**
 * Load all blocklist sources and expose CRUD operations.
 */
export function useBlocklists(): UseBlocklistsReturn {
  const fetcher = useCallback(
    (signal: AbortSignal) => fetchBlocklists(signal),
    [],
  );

  const selector = useCallback((response: BlocklistListResponse) => response.sources, []);

  const { items: sources, loading, error, refresh } = useListData<BlocklistListResponse, BlocklistSource>({
    fetcher,
    selector,
    errorMessage: "Failed to load blocklists",
  });

  const createSource = useCallback(
    async (payload: BlocklistSourceCreate): Promise<BlocklistSource> => {
      const created = await createBlocklist(payload);
      refresh();
      return created;
    },
    [refresh],
  );

  const updateSource = useCallback(
    async (id: number, payload: BlocklistSourceUpdate): Promise<BlocklistSource> => {
      const updated = await updateBlocklist(id, payload);
      refresh();
      return updated;
    },
    [refresh],
  );

  const removeSource = useCallback(
    async (id: number): Promise<void> => {
      await deleteBlocklist(id);
      refresh();
    },
    [refresh],
  );

  const previewSource = useCallback(async (id: number): Promise<PreviewResponse> => {
    const ctrl = new AbortController();
    return previewBlocklist(id, ctrl.signal);
  }, []);

  return {
    sources,
    loading,
    error,
    refresh,
    createSource,
    updateSource,
    removeSource,
    previewSource,
  };
}
