import { describe, it, expect, vi } from "vitest";
import { render, screen } from "@testing-library/react";
import { PrometheusGaugeWidget } from "../PrometheusGaugeWidget";
import type { WidgetInstance } from "../../types";
import * as useWidgets from "../../hooks/useWidgets";

vi.mock("../../hooks/useWidgets", () => ({
	useWidgetData: vi.fn(),
}));

const widget: WidgetInstance = {
	id: "wg1",
	service_id: "s1",
	widget_kind: "gauge",
	title: "CPU Gauge",
	config: {},
	enabled: true,
	sort_order: 0,
	created_at: 0,
	updated_at: 0,
};

function mockData(data: unknown, error?: string) {
	vi.mocked(useWidgets.useWidgetData).mockReturnValue({
		data: error
			? { widget_id: "wg1", error, fetched_at: 0 }
			: { widget_id: "wg1", data, fetched_at: 0 },
		isLoading: false,
	} as unknown as ReturnType<typeof useWidgets.useWidgetData>);
}

describe("PrometheusGaugeWidget", () => {
	it("renders skeleton while loading", () => {
		vi.mocked(useWidgets.useWidgetData).mockReturnValue({
			data: undefined,
			isLoading: true,
		} as unknown as ReturnType<typeof useWidgets.useWidgetData>);
		render(<PrometheusGaugeWidget widget={widget} refreshIntervalMs={30000} />);
		expect(
			document.querySelector('[data-slot="skeleton"]'),
		).toBeInTheDocument();
	});

	it("renders a gauge with value and threshold bands", () => {
		mockData({
			value: 0.75,
			warn_at: 0.8,
			crit_at: 0.95,
			unit: "%",
		});
		render(<PrometheusGaugeWidget widget={widget} refreshIntervalMs={30000} />);
		expect(screen.getByText("CPU Gauge")).toBeInTheDocument();
		expect(screen.getByText(/0.75 %/)).toBeInTheDocument();
		// Threshold labels present when bands are set.
		expect(screen.getByText(/warn/i)).toBeInTheDocument();
		expect(screen.getByText(/crit/i)).toBeInTheDocument();
	});

	it("renders a gauge without threshold bands (single color)", () => {
		mockData({ value: 42, unit: "req/s" });
		render(<PrometheusGaugeWidget widget={widget} refreshIntervalMs={30000} />);
		expect(screen.getByText(/42 req\/s/)).toBeInTheDocument();
		// No threshold labels when bands are absent.
		expect(screen.queryByText(/warn/i)).not.toBeInTheDocument();
	});

	it("shows error Alert on error", () => {
		mockData(null, "Gauge requires a single-series query");
		render(<PrometheusGaugeWidget widget={widget} refreshIntervalMs={30000} />);
		expect(screen.getByText(/single-series/i)).toBeInTheDocument();
	});

	it("shows empty state when no data", () => {
		mockData(null);
		render(<PrometheusGaugeWidget widget={widget} refreshIntervalMs={30000} />);
		expect(screen.getByText(/No data/i)).toBeInTheDocument();
	});
});
