import { describe, it, expect, vi, beforeEach } from "vitest";
import { render, screen } from "@testing-library/react";
import { MemoryRouter, Route, Routes } from "react-router-dom";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { NamedDashboardPage } from "../NamedDashboardPage";

vi.mock("../../hooks/useDashboards", () => ({
	useDashboardBySlug: vi.fn(() => ({ data: undefined, isLoading: true })),
}));

vi.mock("../../hooks/useWidgets", () => ({
	useWidgetReferences: () => ({ data: [] }),
}));

vi.mock("../../components/WidgetConfigDialog", () => ({
	WidgetConfigDialog: () => <div data-testid="config-dialog-stub" />,
}));

vi.mock("../../components/WidgetInstance", () => ({
	WidgetInstanceCard: () => <div data-testid="widget-stub" />,
}));

import { useDashboardBySlug } from "../../hooks/useDashboards";

function renderPage(slug: string) {
	const queryClient = new QueryClient({
		defaultOptions: { queries: { retry: false } },
	});
	return render(
		<QueryClientProvider client={queryClient}>
			<MemoryRouter initialEntries={[`/d/${slug}`]}>
				<Routes>
					<Route path="/d/:slug" element={<NamedDashboardPage />} />
				</Routes>
			</MemoryRouter>
		</QueryClientProvider>,
	);
}

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

	it("renders loading state", () => {
		vi.mocked(useDashboardBySlug).mockReturnValue({
			data: undefined,
			isLoading: true,
			isError: false,
		} as never);
		renderPage("storage");
		// Skeleton renders during load.
		expect(document.querySelector(".h-32")).toBeInTheDocument();
	});

	it("renders 404 when dashboard not found", () => {
		vi.mocked(useDashboardBySlug).mockReturnValue({
			data: undefined,
			isLoading: false,
			isError: true,
		} as never);
		renderPage("nonexistent");
		expect(screen.getByText(/Dashboard not found/i)).toBeInTheDocument();
	});

	it("renders pinned links for a known dashboard", () => {
		vi.mocked(useDashboardBySlug).mockReturnValue({
			data: {
				id: "d1",
				label: "Storage",
				slug: "storage",
				sort_order: 0,
				payload: {
					items: [
						{
							type: "link",
							label: "My Jellyfin",
							target: "/services/jellyfin/svc-1",
						},
					],
				},
				created_at: 1,
				updated_at: 1,
			},
			isLoading: false,
			isError: false,
		} as never);
		renderPage("storage");
		expect(screen.getByText("Storage")).toBeInTheDocument();
		expect(screen.getByText("My Jellyfin")).toBeInTheDocument();
	});

	it("renders empty state when dashboard has no items", () => {
		vi.mocked(useDashboardBySlug).mockReturnValue({
			data: {
				id: "d2",
				label: "Empty",
				slug: "empty",
				sort_order: 0,
				payload: {},
				created_at: 1,
				updated_at: 1,
			},
			isLoading: false,
			isError: false,
		} as never);
		renderPage("empty");
		expect(screen.getByText("Empty")).toBeInTheDocument();
		expect(screen.getByText(/This dashboard is empty/i)).toBeInTheDocument();
	});

	it("renders an edit-widgets button", () => {
		vi.mocked(useDashboardBySlug).mockReturnValue({
			data: {
				id: "d1",
				label: "Storage",
				slug: "storage",
				sort_order: 0,
				payload: { items: [] },
				created_at: 1,
				updated_at: 1,
			},
			isLoading: false,
			isError: false,
		} as never);
		renderPage("storage");
		expect(
			screen.getByRole("button", { name: /Edit widgets/i }),
		).toBeInTheDocument();
	});
});
