"use client";

import { useApiMutation } from "@/presentation/hooks/use-api-mutation";

interface UseApiMutationOpts<TOutput> {
  onSuccess?: (data: TOutput) => void;
  onError?: (error: string) => void;
  successMessage?: string;
}

interface CrudCapableRepo<TEntity, TCreate, TUpdate> {
  create?: (payload: TCreate) => Promise<TEntity>;
  update?: (id: number, payload: TUpdate) => Promise<TEntity>;
  delete?: (id: number) => Promise<void>;
}

interface UseCrudMutationsOptions<TEntity> {
  create?: UseApiMutationOpts<TEntity>;
  update?: UseApiMutationOpts<TEntity>;
  delete?: UseApiMutationOpts<void>;
}

/**
 * Builds the standard create/update/delete mutation triplet against a repository
 * that exposes `create`, `update(id, data)`, and `delete(id)`.
 *
 * Each returned mutation is a regular `useApiMutation` result — semantics, error
 * handling, and toast behavior are identical to wiring them by hand.
 *
 * Pages keep ownership of dialog and edit-target state; this hook only removes
 * the repetitive typing boilerplate.
 */
export function useCrudMutations<TEntity, TCreate, TUpdate>(
  repo: CrudCapableRepo<TEntity, TCreate, TUpdate>,
  options?: UseCrudMutationsOptions<TEntity>
) {
  const create = useApiMutation(
    (data: TCreate) => {
      if (!repo.create) throw new Error("Repository does not support create");
      return repo.create(data);
    },
    options?.create
  );

  const update = useApiMutation(
    ({ id, data }: { id: number; data: TUpdate }) => {
      if (!repo.update) throw new Error("Repository does not support update");
      return repo.update(id, data);
    },
    options?.update
  );

  const remove = useApiMutation(
    (id: number) => {
      if (!repo.delete) throw new Error("Repository does not support delete");
      return repo.delete(id);
    },
    options?.delete
  );

  return { create, update, delete: remove };
}
