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

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

const widget: WidgetInstance = {
	id: "w1",
	service_id: "s1",
	widget_kind: "active",
	title: "Active Torrents",
	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: "w1", error, fetched_at: 0 }
			: { widget_id: "w1", data, fetched_at: 0 },
		isLoading: false,
	} as unknown as ReturnType<typeof useWidgets.useWidgetData>);
}

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

	it("renders active torrent rows", () => {
		mockData({
			torrents: [
				{
					name: "Movie.mkv",
					state: "downloading",
					size: 1000,
					progress: 0.5,
					ratio: 1.25,
					dl_speed: 500000,
					up_speed: 1000,
				},
				{
					name: "Show.mkv",
					state: "uploading",
					size: 2000,
					progress: 1.0,
					dl_speed: 0,
					up_speed: 50000,
				},
			],
		});
		render(
			<QbittorrentActiveTorrentsWidget
				widget={widget}
				refreshIntervalMs={15000}
			/>,
		);
		expect(screen.getByText("Movie.mkv")).toBeInTheDocument();
		expect(screen.getByText("Show.mkv")).toBeInTheDocument();
		expect(screen.getByText("Downloading")).toBeInTheDocument();
		expect(screen.getByText("Uploading")).toBeInTheDocument();
		expect(screen.getByText(/Ratio 1\.25/)).toBeInTheDocument();
	});

	it("shows empty state when no active torrents", () => {
		mockData({ torrents: [] });
		render(
			<QbittorrentActiveTorrentsWidget
				widget={widget}
				refreshIntervalMs={15000}
			/>,
		);
		expect(
			screen.getByText(/No torrents are currently downloading or uploading/i),
		).toBeInTheDocument();
	});

	it("shows error alert on error", () => {
		mockData(null, "qBittorrent fetch failed");
		render(
			<QbittorrentActiveTorrentsWidget
				widget={widget}
				refreshIntervalMs={15000}
			/>,
		);
		expect(screen.getByText(/qBittorrent fetch failed/i)).toBeInTheDocument();
	});
});
