import { useEffect } from "preact/hooks";
import { signal } from "@preact/signals";

export function useFetch<T>(
  url: string,
  options?: FetchOptions,
): {
  data: T | null;
  loading: boolean;
  error: Error | null;
  refetch: (newURL?: string, newOptions?: FetchOptions) => void;
} {
  const data = signal<T | null>(null);
  const loading = signal<boolean>(true);
  const error = signal<Error | null>(null);

  useEffect(() => {
    fetch(url, options)
      .then((response) => {
        if (!response.ok) {
          throw new Error("Failed to fetch data");
        }
        return response.json();
      })
      .then((resp) => (data.value = resp))
      .catch((err) => (error.value = err))
      .finally(() => (loading.value = false));
  }, [url, options]);

  const refetch = (newURL?: string, newOptions?: FetchOptions) => {
    loading.value = true;
    error.value = null;
    fetch(newURL || url, newOptions || options)
      .then((response) => {
        if (!response.ok) {
          throw new Error("Failed to fetch data");
        }
        return response.json();
      })
      .then((resp) => (data.value = resp))
      .catch((err) => (error.value = err))
      .finally(() => (loading.value = false));
  };

  return {
    data: data.value,
    loading: loading.value,
    error: error.value,
    refetch,
  };
}

export interface FetchOptions {
  method: "GET" | "POST" | "PUT" | "DELETE";
  headers: Record<string, string>;
  body: string;
}
