// @vitest-environment jsdom

import { act, renderHook, waitFor } from "@testing-library/react";
import { afterEach, describe, expect, it, vi } from "vitest";
import { emptyCoachForm } from "@/components/sports-admin-client-config";
import { useSportsAdminClientState } from "@/components/use-sports-admin-client-state";
import type { BallboxStoreSportsAdminData } from "@/lib/sports-backend-events";

const initialData: BallboxStoreSportsAdminData = {
  clubs: [{ id: "club_1", name: "Club One" }],
  venues: [{ id: "venue_1", name: "Court One", clubId: "club_1", clubName: "Club One" }],
  coaches: [{ id: "coach_1", name: "Coach One", clubId: null, clubName: null }],
  openMatches: [],
  classes: [],
};

const reloadedData: BallboxStoreSportsAdminData = {
  ...initialData,
  coaches: [{ id: "coach_2", name: "Coach Reloaded", clubId: "club_1", clubName: "Club One" }],
};

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

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

    expect(result.current.data).toEqual(initialData);
    expect(result.current.coachForm).toBe(emptyCoachForm);
    expect(result.current.openMatchForm).toEqual({ venueId: "venue_1", title: "", startsAt: "" });
    expect(result.current.classForm).toEqual({ venueId: "venue_1", title: "", startsAt: "" });
    expect(result.current.message).toBeNull();
    expect(result.current.busy).toBe(false);
  });

  it("reloads sports data after a successful mutation", async () => {
    vi.stubGlobal(
      "fetch",
      vi.fn().mockResolvedValue({
        ok: true,
        json: async () => ({ item: reloadedData }),
      }),
    );

    const { result } = renderHook(() => useSportsAdminClientState(initialData));

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

    await waitFor(() => {
      expect(result.current.data).toEqual(reloadedData);
    });

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

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

    const { result } = renderHook(() => useSportsAdminClientState(initialData));

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

    expect(result.current.data).toEqual(initialData);
    expect(result.current.message).toBe("El venue seleccionado no existe.");
    expect(result.current.busy).toBe(false);
    expect(fetchSpy).not.toHaveBeenCalled();
  });
});
