/**
 * `useHistory` hook — fetches and manages ban history data.
 */

import { useCallback, useEffect, useRef, useState } from "react";
import { fetchHistory, fetchIpHistory } from "../api/history";
import { handleFetchError } from "../utils/fetchError";
import type {
  HistoryBanItem,
  HistoryQuery,
  IpDetailResponse,
} from "../types/history";

// ---------------------------------------------------------------------------
// useHistory — paginated list
// ---------------------------------------------------------------------------

export interface UseHistoryResult {
  items: HistoryBanItem[];
  total: number;
  page: number;
  loading: boolean;
  error: string | null;
  setPage: (page: number) => void;
  refresh: () => void;
}

export function useHistory(query: HistoryQuery = {}): UseHistoryResult {
  const [items, setItems] = useState<HistoryBanItem[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(query.page ?? 1);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const abortRef = useRef<AbortController | null>(null);

  const load = useCallback((): void => {
    abortRef.current?.abort();
    abortRef.current = new AbortController();
    setLoading(true);
    setError(null);

    fetchHistory({ ...query, page })
      .then((resp) => {
        setItems(resp.items);
        setTotal(resp.total);
      })
      .catch((err: unknown) => {
        handleFetchError(err, setError, "Failed to fetch history");
      })
      .finally((): void => {
        setLoading(false);
      });
  }, [query, page]);

  useEffect((): (() => void) => {
    load();
    return (): void => {
      abortRef.current?.abort();
    };
  }, [load]);

  return { items, total, page, loading, error, setPage, refresh: load };
}

// ---------------------------------------------------------------------------
// useIpHistory — per-IP detail
// ---------------------------------------------------------------------------

export interface UseIpHistoryResult {
  detail: IpDetailResponse | null;
  loading: boolean;
  error: string | null;
  refresh: () => void;
}

export function useIpHistory(ip: string): UseIpHistoryResult {
  const [detail, setDetail] = useState<IpDetailResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const abortRef = useRef<AbortController | null>(null);

  const load = useCallback((): void => {
    abortRef.current?.abort();
    abortRef.current = new AbortController();
    setLoading(true);
    setError(null);

    fetchIpHistory(ip)
      .then((resp) => {
        setDetail(resp);
      })
      .catch((err: unknown) => {
        handleFetchError(err, setError, "Failed to fetch IP history");
      })
      .finally((): void => {
        setLoading(false);
      });
  }, [ip]);

  useEffect((): (() => void) => {
    load();
    return (): void => {
      abortRef.current?.abort();
    };
  }, [load]);

  return { detail, loading, error, refresh: load };
}
