import { describe, it, expect, vi, beforeEach } from "vitest";
import { renderHook, act } from "@testing-library/react";
import { invalidateSetupStatus, useSharedSetupStatus } from "../useSharedSetupStatus";
import * as setupApi from "../../api/setup";

vi.mock("../../api/setup");

const mockedGetSetupStatus = vi.mocked(setupApi.getSetupStatus);

describe("useSharedSetupStatus", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    // Invalidate cache to ensure clean state for each test
    invalidateSetupStatus();
  });

  it("returns an object with expected properties", () => {
    mockedGetSetupStatus.mockResolvedValue({ completed: true });

    const { result } = renderHook(() => useSharedSetupStatus());

    expect(result.current).toHaveProperty("status");
    expect(result.current).toHaveProperty("loading");
    expect(result.current).toHaveProperty("error");
    expect(result.current).toHaveProperty("refresh");
    expect(typeof result.current.refresh).toBe("function");
  });

  it("initializes with loading=true", () => {
    mockedGetSetupStatus.mockResolvedValue({ completed: true });

    const { result } = renderHook(() => useSharedSetupStatus());

    expect(result.current.loading).toBe(true);
    expect(result.current.status).toBeNull();
  });

  it("calls getSetupStatus on mount", async () => {
    mockedGetSetupStatus.mockResolvedValue({ completed: true });

    renderHook(() => useSharedSetupStatus());

    await act(async () => {
      await new Promise((resolve) => setTimeout(resolve, 10));
    });

    expect(mockedGetSetupStatus).toHaveBeenCalled();
  });

  it("provides a refresh method", async () => {
    mockedGetSetupStatus.mockResolvedValue({ completed: true });

    const { result } = renderHook(() => useSharedSetupStatus());

    expect(typeof result.current.refresh).toBe("function");

    // Refresh should not throw
    await act(async () => {
      await result.current.refresh();
    });
  });
});
