/**
 * React hook for fetching a single jail's detailed metadata.
 *
 * Reads jail data: configuration, ignore list, ignore self flag, and related state.
 * Does not handle mutations — use `useJailCommands` for write operations.
 */

import { useCallback, useEffect, useRef, useState } from "react";
import { fetchJail } from "../api/jails";
import { handleFetchError, createStringErrorAdapter } from "../utils/fetchError";
import type { Jail } from "../types/jail";

export interface UseJailDataResult {
  jail: Jail | null;
  ignoreList: string[];
  ignoreSelf: boolean;
  loading: boolean;
  error: string | null;
  refresh: () => void;
}

/**
 * Fetch and manage the detail view for a single jail.
 *
 * @param name - The name of the jail to fetch.
 * @returns Jail data and refresh function.
 */
export function useJailData(name: string): UseJailDataResult {
  const [jail, setJail] = useState<Jail | null>(null);
  const [ignoreList, setIgnoreList] = useState<string[]>([]);
  const [ignoreSelf, setIgnoreSelf] = useState(false);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const abortRef = useRef<AbortController | null>(null);

  const refresh = useCallback(() => {
    abortRef.current?.abort();
    const ctrl = new AbortController();
    abortRef.current = ctrl;
    setLoading(true);
    setError(null);

    fetchJail(name)
      .then((res) => {
        if (!ctrl.signal.aborted) {
          setJail(res.jail);
          setIgnoreList(res.ignore_list);
          setIgnoreSelf(res.ignore_self);
        }
      })
      .catch((err: unknown) => {
        if (!ctrl.signal.aborted) {
          handleFetchError(err, createStringErrorAdapter(setError), "Failed to fetch jail detail");
        }
      })
      .finally(() => {
        if (!ctrl.signal.aborted) {
          setLoading(false);
        }
      });
  }, [name]);

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

  return {
    jail,
    ignoreList,
    ignoreSelf,
    loading,
    error,
    refresh,
  };
}
