import { Activity, Clock, Play, RefreshCw, TriangleAlert } from "lucide-react";
import { useState } from "react";
import { LineSeriesChart } from "../../components/LineSeriesChart";
import { chartRangesThrough } from "../../components/chartRanges";
import {
	useRunSchedulerAction,
	useSchedulerRuns,
	useSchedulerSamples,
	useSchedulerStatus,
} from "../../hooks/useScheduler";
import type { ServiceInstance } from "../../types";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";

function formatTimestamp(value: number | null): string {
	return value ? new Date(value * 1000).toLocaleString() : "Never";
}

function statusVariant(
	status: string,
): "default" | "secondary" | "destructive" | "outline" {
	if (status === "success") return "default";
	if (status === "failure") return "destructive";
	if (status === "running") return "secondary";
	return "outline";
}

export function QbittorrentTab({ instance }: { instance: ServiceInstance }) {
	const [windowSeconds, setWindowSeconds] = useState(1800);
	const status = useSchedulerStatus(instance.id);
	const samples = useSchedulerSamples(instance.id, windowSeconds);
	const runs = useSchedulerRuns(instance.id);
	const runNow = useRunSchedulerAction();
	const stale = Boolean(status.data?.enabled && status.data.is_stale);
	const hasError = Boolean(status.data?.last_error || runNow.error);

	const chartSeries = samples.data
		? [
				{
					label: "download",
					points: samples.data.samples.map((sample) => ({
						t: sample.ts * 1000,
						v: sample.dl_speed,
					})),
				},
				{
					label: "upload",
					points: samples.data.samples.map((sample) => ({
						t: sample.ts * 1000,
						v: sample.up_speed,
					})),
				},
			]
		: [];

	return (
		<div className="space-y-4">
			<div className="flex flex-wrap items-center justify-between gap-2">
				<div className="flex items-center gap-2 text-sm text-muted-foreground">
					<Activity className="h-4 w-4" />
					Headless speed polling
					{status.data && (
						<Badge variant={status.data.enabled ? "default" : "secondary"}>
							{status.data.enabled ? "Enabled" : "Paused"}
						</Badge>
					)}
				</div>
				<Button
					onClick={() => runNow.mutate(instance.id)}
					disabled={runNow.isPending || status.data?.running}
					size="sm"
				>
					{runNow.isPending ? (
						<RefreshCw className="mr-2 h-4 w-4 animate-spin" />
					) : (
						<Play className="mr-2 h-4 w-4" />
					)}
					Run now
				</Button>
			</div>

			{(stale || hasError) && (
				<Alert variant={hasError ? "destructive" : "default"}>
					<TriangleAlert className="h-4 w-4" />
					<AlertTitle>
						{hasError ? "Polling error" : "Data may be stale"}
					</AlertTitle>
					<AlertDescription>
						{status.data?.last_error ||
							runNow.error?.message ||
							"No successful sample has been recorded recently."}
					</AlertDescription>
				</Alert>
			)}

			<Card>
				<CardHeader>
					<CardTitle className="flex items-center gap-2">
						<Activity className="h-4 w-4" />
						Speed history
					</CardTitle>
				</CardHeader>
				<CardContent>
					{samples.isLoading ? (
						<Skeleton className="h-[300px] w-full" />
					) : (
						<LineSeriesChart
							series={chartSeries}
							unit="bytes"
							height={300}
							rangeOptions={chartRangesThrough(86400)}
							rangeSeconds={windowSeconds}
							onRangeChange={setWindowSeconds}
						/>
					)}
				</CardContent>
			</Card>

			<div className="grid gap-4 md:grid-cols-3">
				<Card>
					<CardContent className="pt-6">
						<div className="text-xs text-muted-foreground">Last success</div>
						<div className="mt-1 font-medium">
							{formatTimestamp(status.data?.last_success_at ?? null)}
						</div>
					</CardContent>
				</Card>
				<Card>
					<CardContent className="pt-6">
						<div className="text-xs text-muted-foreground">Next poll</div>
						<div className="mt-1 font-medium">
							{formatTimestamp(status.data?.next_run_at ?? null)}
						</div>
					</CardContent>
				</Card>
				<Card>
					<CardContent className="pt-6">
						<div className="text-xs text-muted-foreground">
							Consecutive failures
						</div>
						<div className="mt-1 font-medium">
							{status.data?.consecutive_failures ?? 0}
						</div>
					</CardContent>
				</Card>
			</div>

			<Card>
				<CardHeader>
					<CardTitle className="flex items-center gap-2">
						<Clock className="h-4 w-4" />
						Recent runs
					</CardTitle>
				</CardHeader>
				<CardContent className="space-y-2">
					{runs.isLoading ? (
						<Skeleton className="h-12 w-full" />
					) : runs.data?.items.length ? (
						runs.data.items.map((run) => (
							<div
								key={run.id}
								className="flex flex-wrap items-center justify-between gap-2 rounded-md border p-3 text-sm"
							>
								<div>
									<Badge variant={statusVariant(run.status)}>
										{run.status}
									</Badge>
									<span className="ml-2 text-muted-foreground">
										{run.trigger} · {formatTimestamp(run.started_at)}
									</span>
								</div>
								{run.error && (
									<span className="text-destructive">{run.error}</span>
								)}
							</div>
						))
					) : (
						<div className="text-sm text-muted-foreground">
							No runs recorded yet.
						</div>
					)}
				</CardContent>
			</Card>
		</div>
	);
}
