import { useState } from "react";
import { keepPreviousData, useQuery } from "@tanstack/react-query";
import { healthQuery, statsQuery, timeseriesQuery, upstreamHealthQuery } from "@/lib/queries";
import type { Period } from "@/lib/types";
import InlineError from "@/lib/InlineError";
import { focusRing } from "@/ui/classes";
import DiskCard from "./DiskCard";
import HealthBanners from "./HealthBanners";
import StatCards from "./StatCards";
import TimeseriesChart from "./TimeseriesChart";
import UpstreamHealthTable from "./UpstreamHealthTable";

const PERIODS: Period[] = ["1h", "24h", "7d", "30d"];

function PeriodPicker({ period, onChange }: { period: Period; onChange: (period: Period) => void }) {
	return (
		<div role="group" aria-label="Period" className="flex gap-1">
			{PERIODS.map((option) => (
				<button
					key={option}
					type="button"
					aria-pressed={option === period}
					onClick={() => onChange(option)}
					className={`rounded px-2.5 py-1 text-sm ${focusRing} ${
						option === period
							? "bg-zinc-200 font-medium text-zinc-900 dark:bg-zinc-700 dark:text-zinc-50"
							: "text-zinc-600 hover:bg-zinc-100 dark:text-zinc-400 dark:hover:bg-zinc-800"
					}`}
				>
					{option}
				</button>
			))}
		</div>
	);
}

function Skeleton({ height }: { height: number }) {
	return <div aria-hidden="true" className="animate-pulse rounded bg-zinc-200 dark:bg-zinc-800" style={{ height }} />;
}

export default function DashboardPage() {
	const [period, setPeriod] = useState<Period>("24h");
	const stats = useQuery({ ...statsQuery(period), placeholderData: keepPreviousData });
	const timeseries = useQuery({ ...timeseriesQuery(period), placeholderData: keepPreviousData });
	const health = useQuery(healthQuery());
	const upstreamHealth = useQuery(upstreamHealthQuery());

	return (
		<section className="space-y-4">
			<div className="flex flex-wrap items-center justify-between gap-3">
				<h1 className="text-2xl font-semibold">Dashboard</h1>
				<PeriodPicker period={period} onChange={setPeriod} />
			</div>

			{health.data !== undefined && <HealthBanners health={health.data} />}

			{stats.isError ? (
				<InlineError error={stats.error} onRetry={() => void stats.refetch()} />
			) : stats.data === undefined ? (
				<Skeleton height={76} />
			) : (
				<StatCards stats={stats.data} />
			)}

			<div className="grid gap-4 lg:grid-cols-[2fr_1fr]">
				<section className="rounded border border-zinc-200 bg-white px-4 py-3 dark:border-zinc-800 dark:bg-zinc-900">
					<h2 className="mb-3 text-sm font-semibold">Queries over time</h2>
					{timeseries.isError ? (
						<InlineError error={timeseries.error} onRetry={() => void timeseries.refetch()} />
					) : timeseries.data === undefined ? (
						<Skeleton height={240} />
					) : (
						<TimeseriesChart data={timeseries.data} />
					)}
				</section>
				{health.data === undefined ? <Skeleton height={160} /> : <DiskCard disk={health.data.disk} />}
			</div>

			{upstreamHealth.isError ? (
				<InlineError error={upstreamHealth.error} onRetry={() => void upstreamHealth.refetch()} />
			) : upstreamHealth.data === undefined ? (
				<Skeleton height={120} />
			) : (
				<UpstreamHealthTable health={upstreamHealth.data} />
			)}
		</section>
	);
}
