import { describe, it, expect, vi } from "vitest";
import { renderHook } from "@testing-library/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { createElement, type ReactNode } from "react";
import { useBackupJobs, useBackupRuns, useBackupAlerts } from "../useBackups";
import {
	useAlertmanagerAlerts,
	usePrometheusStatus,
} from "../useObservability";

vi.mock("../../api/client", () => ({
	fetchAlertmanagerAlerts: vi.fn(),
	fetchAlertmanagerStatus: vi.fn(),
	fetchPrometheusStatus: vi.fn(),
	fetchPrometheusTargets: vi.fn(),
	fetchMonitoringMachines: vi.fn(),
}));
vi.mock("../../api/backups", () => ({
	fetchBackupJobs: vi.fn(),
	fetchBackupRuns: vi.fn(),
	fetchBackupAlerts: vi.fn(),
	fetchBackupDashboard: vi.fn(),
	fetchBackupJob: vi.fn(),
	acknowledgeBackupAlert: vi.fn(),
}));

function createWrapper() {
	const queryClient = new QueryClient({
		defaultOptions: { queries: { retry: false } },
	});
	return ({ children }: { children: ReactNode }) =>
		createElement(QueryClientProvider, { client: queryClient }, children);
}

describe("per-instance hook queryKey isolation", () => {
	it("useBackupJobs produces different keys for different serviceIds", () => {
		const wrapper = createWrapper();
		const { result: a } = renderHook(() => useBackupJobs("svc-a"), { wrapper });
		const { result: b } = renderHook(() => useBackupJobs("svc-b"), { wrapper });
		expect(a).toBeDefined();
		expect(b).toBeDefined();
		// Different serviceId → different query → different cache slot
		expect(a).not.toBe(b);
	});

	it("useBackupJobs with undefined serviceId is stable (same key)", () => {
		const wrapper = createWrapper();
		const { result: a } = renderHook(() => useBackupJobs(), { wrapper });
		const { result: b } = renderHook(() => useBackupJobs(), { wrapper });
		expect(a).toBeDefined();
		expect(b).toBeDefined();
	});

	it("useBackupRuns includes serviceId in queryKey", () => {
		const wrapper = createWrapper();
		const { result: a } = renderHook(
			() => useBackupRuns(undefined, undefined, "svc-a"),
			{ wrapper },
		);
		expect(a).toBeDefined();
	});

	it("useBackupAlerts includes serviceId in queryKey", () => {
		const wrapper = createWrapper();
		const { result: a } = renderHook(
			() => useBackupAlerts(undefined, false, undefined, "svc-a"),
			{ wrapper },
		);
		expect(a).toBeDefined();
	});

	it("useAlertmanagerAlerts includes serviceId in queryKey", () => {
		const wrapper = createWrapper();
		const { result: a } = renderHook(() => useAlertmanagerAlerts("svc-a"), {
			wrapper,
		});
		expect(a).toBeDefined();
	});

	it("usePrometheusStatus includes serviceId in queryKey", () => {
		const wrapper = createWrapper();
		const { result: a } = renderHook(() => usePrometheusStatus("svc-a"), {
			wrapper,
		});
		expect(a).toBeDefined();
	});
});
