import { useRef } from "react";
import { useFetcher } from "react-router";
import { toast } from "sonner";
import type { CoreAPIError } from "./types";

interface FetcherQueryOptions<TData> {
  onSuccess?: (data: TData) => void;
  onError?: (error: unknown) => void;
}

interface FetcherQueryReturn<TData> {
  trigger: (formData?: Record<string, unknown>) => Promise<void>;
  isLoading: boolean;
  data: TData | null;
}

export function useCoreFetcher<TData>(
  intent: string,
  method: "post" | "put" | "delete" | "patch",
  options?: FetcherQueryOptions<TData>,
): FetcherQueryReturn<TData> {
  const fetcher = useFetcher();
  const pendingCallback = useRef<((data: unknown) => void) | null>(null);

  const isLoading = fetcher.state === "submitting";
  if (fetcher.state === "idle" && pendingCallback.current) {
    pendingCallback.current(fetcher.data as TData);
    pendingCallback.current = null;
  }

  const trigger = (formData?: Record<string, unknown>) => {
    return new Promise<void>((resolve) => {
      const submitData = {
        intent,
        ...formData,
      };

      pendingCallback.current = (data: unknown) => {
        const response = data as CoreAPIError;
        if (response?.success === false) {
          const errorMessage = response?.message ?? "An error occurred";
          toast.error(errorMessage);
          options?.onError?.(data);
        } else {
          options?.onSuccess?.(data as TData);
        }
        resolve();
      };

      fetcher.submit(submitData, {
        encType: "application/json",
        method,
      });
    });
  };

  return {
    trigger,
    isLoading,
    data: fetcher.data || null,
  };
}
