// @vitest-environment jsdom

import { act, renderHook, waitFor } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vitest";
import { emptyPlayerForm } from "@/components/players-admin-client-config";
import { usePlayersAdminClientState } from "@/components/use-players-admin-client-state";
import type { BallboxStoreAdminPlayer } from "@/lib/ballbox-store";

const initialPlayers: BallboxStoreAdminPlayer[] = [
  {
    id: "player_1",
    name: "Player One",
    whatsappPhone: null,
    telegramHandle: null,
    gender: null,
    birthYear: null,
    coachCategory: null,
    memberships: [
      {
        id: "membership_1",
        clubId: "club_1",
        clubName: "Club One",
      },
    ],
  },
];

const reloadedPlayers: BallboxStoreAdminPlayer[] = [
  {
    id: "player_2",
    name: "Player Reloaded",
    whatsappPhone: null,
    telegramHandle: null,
    gender: null,
    birthYear: null,
    coachCategory: null,
    memberships: [],
  },
];

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

  it("starts from shared local defaults", () => {
    const { result } = renderHook(() => usePlayersAdminClientState(initialPlayers));

    expect(result.current.players).toEqual(initialPlayers);
    expect(result.current.playerForm).toBe(emptyPlayerForm);
    expect(result.current.membershipClubIds).toEqual({});
    expect(result.current.message).toBeNull();
    expect(result.current.busy).toBe(false);
  });

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

    const { result } = renderHook(() => usePlayersAdminClientState(initialPlayers));

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

    await waitFor(() => {
      expect(result.current.players).toEqual(reloadedPlayers);
    });

    expect(result.current.message).toBe("Player updated");
    expect(result.current.busy).toBe(false);
    expect(fetch).toHaveBeenCalledWith("/api/admin/players", { cache: "no-store" });
  });

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

    const { result } = renderHook(() => usePlayersAdminClientState(initialPlayers));

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

    expect(result.current.players).toEqual(initialPlayers);
    expect(result.current.message).toBe("Ya existe otro player con ese nombre.");
    expect(result.current.busy).toBe(false);
    expect(fetchSpy).not.toHaveBeenCalled();
  });
});
