import { Alert, AlertDescription } from "@/components/ui/alert";
import { Badge } from "@/components/ui/badge";
import { Skeleton } from "@/components/ui/skeleton";
import { SectionCard } from "../components/SectionCard";
import { useWidgetData } from "../hooks/useWidgets";
import type { WidgetInstance } from "../types";

interface Props {
	widget: WidgetInstance;
	refreshIntervalMs: number;
	description?: string;
}

interface ActiveTorrent {
	name: string | null;
	state: string | null;
	direction?: "downloading" | "uploading";
	size: number | null;
	progress: number | null;
	dl_speed: number | null;
	up_speed: number | null;
}

function formatSpeed(bytesPerSec: number | null): string {
	if (bytesPerSec === null || bytesPerSec <= 0) return "—";
	const mb = bytesPerSec / 1_000_000;
	if (mb >= 1) return `${mb.toFixed(1)} MB/s`;
	return `${(bytesPerSec / 1000).toFixed(0)} KB/s`;
}

function formatSize(bytes: number | null): string {
	if (bytes === null || bytes < 0) return "Size unknown";
	if (bytes >= 1_000_000_000) return `${(bytes / 1_000_000_000).toFixed(1)} GB`;
	if (bytes >= 1_000_000) return `${(bytes / 1_000_000).toFixed(1)} MB`;
	return `${(bytes / 1_000).toFixed(0)} KB`;
}

function formatProgress(progress: number | null): string {
	if (progress === null) return "Progress unknown";
	return `${Math.round(progress * 100)}% complete`;
}

function formatState(
	state: string | null,
	direction?: ActiveTorrent["direction"],
): string {
	const labels: Record<string, string> = {
		downloading: "Downloading",
		forcedDL: "Downloading",
		stalledDL: "Download stalled",
		queuedDL: "Queued download",
		metaDL: "Downloading metadata",
		forcedMetaDL: "Downloading metadata",
		checkingDL: "Checking download",
		allocating: "Allocating",
		uploading: "Uploading",
		forcedUP: "Uploading",
		stalledUP: "Upload stalled",
		queuedUP: "Queued upload",
		checkingUP: "Checking upload",
		checkingResumeData: "Checking resume data",
		moving: "Moving",
	};
	if (state && labels[state]) return labels[state];
	if (direction)
		return direction === "downloading" ? "Downloading" : "Uploading";
	return state || "Unknown state";
}

export function QbittorrentActiveTorrentsWidget({
	widget,
	refreshIntervalMs,
	description,
}: Props) {
	const { data, isLoading } = useWidgetData(widget.id, refreshIntervalMs);
	const payload = data?.data as { torrents?: ActiveTorrent[] } | undefined;
	const torrents = payload?.torrents ?? [];

	return (
		<SectionCard title={widget.title} description={description}>
			{isLoading && !data ? (
				<div className="space-y-2">
					<Skeleton className="h-12 w-full" />
					<Skeleton className="h-12 w-full" />
				</div>
			) : data?.error ? (
				<Alert variant="destructive">
					<AlertDescription>{data.error}</AlertDescription>
				</Alert>
			) : torrents.length > 0 ? (
				<ul className="max-h-96 space-y-1.5 overflow-y-auto">
					{torrents.map((torrent, index) => {
						const direction = torrent.direction;
						return (
							<li
								key={`${torrent.name}-${torrent.state}-${index}`}
								className="rounded-md border px-3 py-2 text-sm"
							>
								<div className="flex items-start justify-between gap-2">
									<div className="min-w-0">
										<p className="truncate font-medium">
											{torrent.name ?? "Unknown torrent"}
										</p>
										<p className="text-xs text-muted-foreground">
											{formatSize(torrent.size)} ·{" "}
											{formatProgress(torrent.progress)}
										</p>
									</div>
									<Badge
										variant={
											direction === "downloading" ? "default" : "secondary"
										}
									>
										{formatState(torrent.state, direction)}
									</Badge>
								</div>
								<div className="mt-1 text-xs text-muted-foreground">
									↓ {formatSpeed(torrent.dl_speed)} · ↑{" "}
									{formatSpeed(torrent.up_speed)}
								</div>
							</li>
						);
					})}
				</ul>
			) : (
				<div className="text-xs text-muted-foreground">
					No torrents are currently downloading or uploading.
				</div>
			)}
		</SectionCard>
	);
}
