/**
 * `useServerStatus` hook.
 *
 * Fetches and periodically refreshes the fail2ban server health snapshot
 * from `GET /api/dashboard/status`.  Also refetches on window focus so the
 * status is always fresh when the user returns to the tab.
 */

import { useCallback, useEffect, useRef, useState } from "react";
import { fetchServerStatus } from "../api/dashboard";
import { handleFetchError } from "../utils/fetchError";
import type { ServerStatus } from "../types/server";

/** How often to poll the status endpoint (milliseconds). */
const POLL_INTERVAL_MS = 30_000;

/** Return value of the {@link useServerStatus} hook. */
export interface UseServerStatusResult {
  /** The most recent server status snapshot, or `null` before the first fetch. */
  status: ServerStatus | null;
  /** Whether a fetch is currently in flight. */
  loading: boolean;
  /** Error message string when the last fetch failed, otherwise `null`. */
  error: string | null;
  /** Manually trigger a refresh immediately. */
  refresh: () => void;
}

/**
 * Poll `GET /api/dashboard/status` every 30 seconds and on window focus.
 *
 * @returns Current status, loading state, error, and a `refresh` callback.
 */
export function useServerStatus(): UseServerStatusResult {
  const [status, setStatus] = useState<ServerStatus | null>(null);
  const [loading, setLoading] = useState<boolean>(true);
  const [error, setError] = useState<string | null>(null);

  // Use a ref so the fetch function identity is stable.
  const fetchRef = useRef<() => Promise<void>>(async () => Promise.resolve());

  const doFetch = useCallback(async (): Promise<void> => {
    setLoading(true);
    try {
      const data = await fetchServerStatus();
      setStatus(data.status);
      setError(null);
    } catch (err: unknown) {
      handleFetchError(err, setError, "Failed to fetch server status");
    } finally {
      setLoading(false);
    }
  }, []);

  fetchRef.current = doFetch;

  // Initial fetch + polling interval.
  useEffect((): (() => void) => {
    void doFetch().catch((): void => undefined);

    const id = setInterval((): void => {
      void fetchRef.current().catch((): void => undefined);
    }, POLL_INTERVAL_MS);

    return (): void => { clearInterval(id); };
  }, [doFetch]);

  // Refetch on window focus.
  useEffect(() => {
    const onFocus = (): void => {
      void fetchRef.current();
    };
    window.addEventListener("focus", onFocus);
    return (): void => { window.removeEventListener("focus", onFocus); };
  }, []);

  const refresh = useCallback((): void => {
    void doFetch().catch((): void => undefined);
  }, [doFetch]);

  return { status, loading, error, refresh };
}
