import { describe, expect, test } from "vitest";
import { renderHook, waitFor } from "@testing-library/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import type { ReactNode } from "react";

import {
  useAuthorities,
  useCreateObject,
  useDeleteObject,
  useSetFields,
  useTerms,
  useUpdateObject,
} from "./queries";

function wrapper({ children }: { children: ReactNode }) {
  const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } });

  return <QueryClientProvider client={qc}>{children}</QueryClientProvider>;
}

describe("authoring hooks", () => {
  test("useTerms loads a vocabulary's terms", async () => {
    const { result } = renderHook(() => useTerms("v-material"), { wrapper });

    await waitFor(() => expect(result.current.data).toBeDefined());
    expect(result.current.data?.[0].id).toBe("t-bronze");
  });

  test("useAuthorities loads by kind", async () => {
    const { result } = renderHook(() => useAuthorities("person"), { wrapper });

    await waitFor(() => expect(result.current.data?.length).toBe(1));
    expect(result.current.data?.[0].id).toBe("a-ada");
  });

  test("useCreateObject returns the new id", async () => {
    const { result } = renderHook(() => useCreateObject(), { wrapper });

    const created = await result.current.mutateAsync({
      object_number: "A-1",
      object_name: "x",
      number_of_objects: 1,
      visibility: "draft",
    });

    expect(created.id).toBe("11111111-1111-1111-1111-111111111111");
  });

  test("useSetFields / useUpdateObject / useDeleteObject resolve", async () => {
    const setFields = renderHook(() => useSetFields(), { wrapper });

    await setFields.result.current.mutateAsync({ id: "o1", fields: { inscription: "hi" } });

    const update = renderHook(() => useUpdateObject(), { wrapper });

    await update.result.current.mutateAsync({
      id: "o1",
      body: { object_number: "A-1", object_name: "x", number_of_objects: 1 },
    });

    const del = renderHook(() => useDeleteObject(), { wrapper });

    await del.result.current.mutateAsync("o1");

    expect(true).toBe(true);
  });
});
