"use client";

import { useCallback, useEffect, useRef, useState } from "react";

export async function api<T = unknown>(url: string, options?: RequestInit): Promise<T> {
  const res = await fetch(url, {
    headers: { "Content-Type": "application/json" },
    ...options,
  });
  const data = await res.json().catch(() => ({}));
  if (!res.ok) {
    throw new Error((data as { error?: string }).error || "Request failed");
  }
  return data as T;
}

/** Small data-fetching hook with manual reload support. */
export function useApi<T = unknown>(url: string | null) {
  const [data, setData] = useState<T | null>(null);
  const [loading, setLoading] = useState(!!url);
  const [error, setError] = useState<string | null>(null);
  const hasData = useRef(false);

  const load = useCallback(
    async (silent = false) => {
      if (!url) return;
      // Initial and url-driven fetches toggle the loading state so pages can
      // show a loader. Manual reload() refreshes SILENTLY: the previous data
      // stays on screen and swaps in place when the fresh data lands — no
      // loader flash or layout jump after actions (approve/save/delete/...).
      if (!silent || !hasData.current) setLoading(true);
      setError(null);
      try {
        const result = await api<T>(url);
        hasData.current = true;
        setData(result);
      } catch (e) {
        setError(e instanceof Error ? e.message : "Failed to load");
      } finally {
        setLoading(false);
      }
    },
    [url]
  );

  useEffect(() => {
    hasData.current = false;
    load();
  }, [load]);

  const reload = useCallback(() => load(true), [load]);

  return { data, loading, error, reload };
}
