import { describe, expect, test } from "vitest";
import { renderHook, waitFor } from "@testing-library/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { http, HttpResponse } from "msw";
import type { ReactNode } from "react";
import { server } from "../test/server";
import { useVocabularies, useCreateVocabulary, useAddTerm, useCreateAuthority } from "./queries";

function wrapper({ children }: { children: ReactNode }) {
  const qc = new QueryClient({ defaultOptions: { queries: { retry: false } } });
  return <QueryClientProvider client={qc}>{children}</QueryClientProvider>;
}

describe("vocab/authority hooks", () => {
  test("useVocabularies lists vocabularies", async () => {
    const { result } = renderHook(() => useVocabularies(), { wrapper });
    await waitFor(() => expect(result.current.data?.length).toBe(2));
    expect(result.current.data?.[0].key).toBe("material");
  });
  test("useCreateVocabulary POSTs the key", async () => {
    let body: unknown;
    server.use(http.post("/api/admin/vocabularies", async ({ request }) => {
      body = await request.json();
      return HttpResponse.json({ id: "v-x", key: "colour" }, { status: 201 });
    }));
    const { result } = renderHook(() => useCreateVocabulary(), { wrapper });
    await result.current.mutateAsync({ key: "colour" });
    expect((body as { key: string }).key).toBe("colour");
  });
  test("useAddTerm POSTs labels to the vocabulary", async () => {
    let body: unknown;
    server.use(http.post("/api/admin/vocabularies/:id/terms", async ({ request }) => {
      body = await request.json();
      return HttpResponse.json({ id: "t-x" }, { status: 201 });
    }));
    const { result } = renderHook(() => useAddTerm(), { wrapper });
    await result.current.mutateAsync({ vocabularyId: "v-material", external_uri: null, labels: [{ lang: "en", label: "Red" }] });
    expect((body as { labels: { label: string }[] }).labels[0].label).toBe("Red");
  });
  test("useCreateAuthority POSTs kind + labels", async () => {
    let body: unknown;
    server.use(http.post("/api/admin/authorities", async ({ request }) => {
      body = await request.json();
      return HttpResponse.json({ id: "a-x" }, { status: 201 });
    }));
    const { result } = renderHook(() => useCreateAuthority(), { wrapper });
    await result.current.mutateAsync({ kind: "person", external_uri: null, labels: [{ lang: "en", label: "Ada" }] });
    expect((body as { kind: string }).kind).toBe("person");
  });
});
