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 () => {
        // @ts-ignore
        const res = await api.get<T[]>(endpoint, { params });
        return res.data;
      }
    });

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

  // --- CREATE ---
  const useCreate = () =>
    useMutation({
      mutationFn: async (data: Partial<T>) => {
        // @ts-ignore
        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> }) => {
        // @ts-ignore
        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"] });
      },
    });

  // --- HELPERS FOR useQueries ---
  const getListQueryOptions = (params?: any) => ({
    queryKey: [name, "list", params],
    queryFn: async () => {
      // @ts-ignore
      const res = await api.get<T[]>(endpoint, { params });
      return res.data;
    },
  });

  // --- READ ME ---
  const useMe = () =>
    useQuery({
      queryKey: [name, "me"],
      queryFn: async () => {
        // @ts-ignore
        const res = await api.get<T>(`${endpoint}/me`);
        return res.data;
      },
    });

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

  return {
    useList,
    useRead,
    useMe,
    useCreate,
    useUpdate,
    useUpdateMe,
    useDelete,
    getListQueryOptions,
  };
}
