import { describe, it, expect, vi, beforeEach } from "vitest";
import { renderHook, act } from "@testing-library/react";
import * as configApi from "../../api/config";
import { useJailConfigs } from "../useJailConfigs";

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

describe("useJailConfigs", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("calls fetchJailConfigs only once on mount", async () => {
    vi.mocked(configApi.fetchJailConfigs).mockResolvedValue({
      jails: [
        {
          name: "sshd",
          ban_time: 600,
          find_time: 600,
          max_retry: 5,
          fail_regex: [],
          ignore_regex: [],
          log_paths: [],
          date_pattern: null,
          log_encoding: "auto",
          backend: "systemd",
          use_dns: "warn",
          prefregex: "",
          actions: [],
          bantime_escalation: null,
        },
      ],
      total: 1,
    });

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

    expect(result.current.loading).toBe(true);

    await act(async () => {
      await Promise.resolve();
    });

    expect(configApi.fetchJailConfigs).toHaveBeenCalledTimes(1);
    expect(result.current.jails).toHaveLength(1);
    expect(result.current.total).toBe(1);
    expect(result.current.loading).toBe(false);
  });

  it("does not trigger infinite refetch with stable onSuccess", async () => {
    vi.mocked(configApi.fetchJailConfigs).mockResolvedValue({
      jails: [],
      total: 0,
    });

    const { rerender } = renderHook(() => useJailConfigs());

    await act(async () => {
      await Promise.resolve();
    });

    const callCountAfterMount = vi.mocked(configApi.fetchJailConfigs).mock.calls.length;

    // Re-render multiple times to ensure no additional fetches are triggered
    rerender();
    await act(async () => {
      await Promise.resolve();
    });

    rerender();
    await act(async () => {
      await Promise.resolve();
    });

    const callCountAfterRerender = vi.mocked(configApi.fetchJailConfigs).mock.calls.length;

    // Should still be called only once (on mount)
    expect(callCountAfterRerender).toBe(callCountAfterMount);
  });
});
