import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { api } from "../api/client";
import { ResourceConfig } from "../types/config";

export function useResource<T = any>(config: ResourceConfig) {
  const queryClient = useQueryClient();
  const { name, endpoint, primaryKey } = config;

  // --- READ ALL ---
  const useList = (params?: any) => 
    useQuery({
      queryKey: [name, "list", params],
      queryFn: async () => {
        const res = await api.get<T[]>(endpoint, { params });
        return res.data;
      }
    });

  // --- READ ONE ---
  const useOne = (id: string | null) =>
    useQuery({
      queryKey: [name, "detail", id],
      queryFn: async () => {
        if (!id) return null;
        const res = await api.get<T>(`${endpoint}/${id}`);
        return res.data;
      },
      enabled: !!id,
    });

  // --- CREATE ---
  const useCreate = () =>
    useMutation({
      mutationFn: async (data: Partial<T>) => {
        const res = await api.post<T>(endpoint, data);
        return res.data;
      },
      onSuccess: () => {
        queryClient.invalidateQueries({ queryKey: [name, "list"] });
      },
    });

  // --- UPDATE ---
  const useUpdate = () =>
    useMutation({
      mutationFn: async ({ id, data }: { id: string; data: Partial<T> }) => {
        const res = await api.put<T>(`${endpoint}/${id}`, data);
        return res.data;
      },
      onSuccess: (updatedItem) => {
        // @ts-ignore
        const id = updatedItem[primaryKey];
        queryClient.invalidateQueries({ queryKey: [name, "list"] });
        queryClient.invalidateQueries({ queryKey: [name, "detail", id] });
      },
    });

  // --- DELETE ---
  const useDelete = () =>
    useMutation({
      mutationFn: async (id: string) => {
        await api.delete(`${endpoint}/${id}`);
        return id;
      },
      onSuccess: () => {
        queryClient.invalidateQueries({ queryKey: [name, "list"] });
      },
    });

  return {
    useList,
    useOne,
    useCreate,
    useUpdate,
    useDelete,
  };
}
