import { useState, useCallback, useEffect } from "react";
import { useAdminData } from "./useAdminData";
import { useAdminToast } from "./useAdminToast";
import { apiClient } from "@/lib/api/client";

interface UseCRUDOptions<T> {
  fetchFn: () => Promise<T[]>;
  createFn: (item: Omit<T, "id">) => Promise<T>;
  updateFn: (id: number, item: Partial<T>) => Promise<T>;
  deleteFn: (id: number) => Promise<void>;
  onSuccess?: (action: "create" | "update" | "delete", item: T) => void;
  onError?: (action: "create" | "update" | "delete", error: Error) => void;
}

export function useCRUD<T extends { id?: number }>({
  fetchFn,
  createFn,
  updateFn,
  deleteFn,
  onSuccess,
  onError,
}: UseCRUDOptions<T>) {
  const { data, loading, error, refetch } = useAdminData({
    fetchFn,
  });
  const { showSuccess, showError } = useAdminToast();
  const [items, setItems] = useState<T[]>([]);

  // Update items when data changes
  useEffect(() => {
    if (data) {
      setItems(data);
    }
  }, [data]);

  const create = useCallback(
    async (item: Omit<T, "id">) => {
      try {
        const newItem = await createFn(item);
        setItems((prev) => [...prev, newItem]);
        showSuccess("Item created successfully!");
        onSuccess?.("create", newItem);
        // Invalidate cache
        apiClient.clearCache();
        return newItem;
      } catch (err) {
        const error = err instanceof Error ? err : new Error("Failed to create item");
        showError(error.message);
        onError?.("create", error);
        throw error;
      }
    },
    [createFn, showSuccess, showError, onSuccess, onError]
  );

  const update = useCallback(
    async (id: number, item: Partial<T>) => {
      try {
        const updatedItem = await updateFn(id, item);
        setItems((prev) => prev.map((i) => (i.id === id ? updatedItem : i)));
        showSuccess("Item updated successfully!");
        onSuccess?.("update", updatedItem);
        // Invalidate cache
        apiClient.clearCache();
        return updatedItem;
      } catch (err) {
        const error = err instanceof Error ? err : new Error("Failed to update item");
        showError(error.message);
        onError?.("update", error);
        throw error;
      }
    },
    [updateFn, showSuccess, showError, onSuccess, onError]
  );

  const remove = useCallback(
    async (id: number) => {
      try {
        await deleteFn(id);
        setItems((prev) => prev.filter((i) => i.id !== id));
        showSuccess("Item deleted successfully!");
        const deletedItem = items.find((i) => i.id === id);
        if (deletedItem) {
          onSuccess?.("delete", deletedItem);
        }
        // Invalidate cache
        apiClient.clearCache();
      } catch (err) {
        const error = err instanceof Error ? err : new Error("Failed to delete item");
        showError(error.message);
        onError?.("delete", error);
        throw error;
      }
    },
    [deleteFn, items, showSuccess, showError, onSuccess, onError]
  );

  return {
    items,
    loading,
    error,
    create,
    update,
    remove,
    refetch,
  };
}

