// @vitest-environment jsdom

import { act, renderHook, waitFor } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vitest";
import { useNetworkAdminClientState } from "@/components/use-network-admin-client-state";
import type { BallboxStoreClubDetail } from "@/lib/ballbox-store";

const initialClubs: BallboxStoreClubDetail[] = [
  {
    id: "club_1",
    atcSportclubId: "101",
    name: "Club One",
    locationName: "Buenos Aires",
    venues: [],
  },
];

const reloadedClubs: BallboxStoreClubDetail[] = [
  {
    id: "club_2",
    atcSportclubId: "102",
    name: "Club Reloaded",
    locationName: "Cordoba",
    venues: [],
  },
];

describe("useNetworkAdminClientState", () => {
  afterEach(() => {
    vi.restoreAllMocks();
  });

  it("reloads clubs after a successful mutation", async () => {
    vi.stubGlobal(
      "fetch",
      vi.fn().mockResolvedValue({
        ok: true,
        json: async () => ({ items: reloadedClubs }),
      }),
    );

    const { result } = renderHook(() => useNetworkAdminClientState(initialClubs));

    await act(async () => {
      await result.current.runMutation(async () => {}, "Club updated");
    });

    await waitFor(() => {
      expect(result.current.clubs).toEqual(reloadedClubs);
    });

    expect(result.current.message).toBe("Club updated");
    expect(result.current.messageTone).toBe("success");
    expect(result.current.busy).toBe(false);
    expect(fetch).toHaveBeenCalledWith("/api/network?include=details", { cache: "no-store" });
  });

  it("surfaces mutation errors without reloading", async () => {
    const fetchSpy = vi.fn();
    vi.stubGlobal("fetch", fetchSpy);

    const { result } = renderHook(() => useNetworkAdminClientState(initialClubs));

    await act(async () => {
      await result.current.runMutation(async () => {
        throw new Error("boom");
      }, "Club updated");
    });

    expect(result.current.clubs).toEqual(initialClubs);
    expect(result.current.message).toBe("boom");
    expect(result.current.messageTone).toBe("error");
    expect(result.current.busy).toBe(false);
    expect(fetchSpy).not.toHaveBeenCalled();
  });
});
