import { useState } from "react";
import { keepPreviousData, useQuery } from "@tanstack/react-query";
import * as stylex from "@stylexjs/stylex";
import { healthQuery, statsQuery, timeseriesQuery, upstreamHealthQuery } from "@/lib/queries";
import type { Period } from "@/lib/types";
import InlineError from "@/lib/InlineError";
import { styles as shared } from "@/ui/styles";
import { colors } from "@/ui/tokens.stylex";
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"];

const styles = stylex.create({
	page: {
		display: "flex",
		flexDirection: "column",
		gap: "1rem",
	},
	titleRow: {
		display: "flex",
		flexWrap: "wrap",
		alignItems: "center",
		justifyContent: "space-between",
		gap: "0.75rem",
	},
	heading: {
		fontSize: "1.5rem",
		lineHeight: "2rem",
		fontWeight: 600,
	},
	periodGroup: {
		display: "flex",
		gap: "0.25rem",
	},
	period: {
		borderStyle: "none",
		borderRadius: "0.25rem",
		paddingInline: "0.625rem",
		paddingBlock: "0.25rem",
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
	},
	/** The pressed fill is heavier than `surfaceHover`, so a hover cannot mimic it. */
	periodSelected: {
		backgroundColor: {
			default: "oklch(92% 0.004 286.32)",
			"@media (prefers-color-scheme: dark)": "oklch(37% 0.013 285.805)",
		},
		color: colors.text,
		fontWeight: 500,
	},
	periodIdle: {
		backgroundColor: { default: "transparent", ":hover": colors.surfaceHover },
		color: colors.textSecondary,
	},
	/** Dynamic: the caller sizes the placeholder to the widget it stands in for. */
	skeletonHeight: (height: number) => ({ height }),
	skeleton: {
		borderRadius: "0.25rem",
		backgroundColor: {
			default: "oklch(92% 0.004 286.32)",
			"@media (prefers-color-scheme: dark)": "oklch(27.4% 0.006 286.033)",
		},
	},
	/** The chart takes two thirds beside the disk card from `lg`, one column below. */
	panelGrid: {
		display: "grid",
		gap: "1rem",
		gridTemplateColumns: {
			default: "repeat(1, minmax(0, 1fr))",
			"@media (min-width: 1024px)": "2fr 1fr",
		},
	},
	panel: {
		borderRadius: "0.25rem",
		borderWidth: 1,
		borderStyle: "solid",
		borderColor: colors.border,
		backgroundColor: colors.surfaceRaised,
		paddingInline: "1rem",
		paddingBlock: "0.75rem",
	},
	panelHeading: {
		marginBottom: "0.75rem",
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
		fontWeight: 600,
	},
});

function PeriodPicker({ period, onChange }: { period: Period; onChange: (period: Period) => void }) {
	return (
		<div role="group" aria-label="Period" {...stylex.props(styles.periodGroup)}>
			{PERIODS.map((option) => (
				<button
					key={option}
					type="button"
					aria-pressed={option === period}
					onClick={() => onChange(option)}
					{...stylex.props(
						styles.period,
						option === period ? styles.periodSelected : styles.periodIdle,
						shared.focusRing,
					)}
				>
					{option}
				</button>
			))}
		</div>
	);
}

function Skeleton({ height }: { height: number }) {
	return <div aria-hidden="true" {...stylex.props(styles.skeleton, styles.skeletonHeight(height), shared.pulse)} />;
}

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 {...stylex.props(styles.page)}>
			<div {...stylex.props(styles.titleRow)}>
				<h1 {...stylex.props(styles.heading)}>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 {...stylex.props(styles.panelGrid)}>
				<section {...stylex.props(styles.panel)}>
					<h2 {...stylex.props(styles.panelHeading)}>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>
	);
}
