import { useEffect, useState } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import * as stylex from "@stylexjs/stylex";
import { pauseMutation, pauseQuery } from "@/lib/queries";
import InlineError from "@/lib/InlineError";
import { styles as shared } from "@/ui/styles";
import { colors } from "@/ui/tokens.stylex";

const DURATIONS = [
	{ label: "60 seconds", seconds: 60 },
	{ label: "5 minutes", seconds: 300 },
	{ label: "30 minutes", seconds: 1800 },
	{ label: "Indefinitely", seconds: null },
] as const;

const styles = stylex.create({
	/**
	 * Disabled text darkens in light scheme and lightens in dark, the opposite
	 * direction from `textMuted`, so the token cannot express it.
	 */
	trigger: {
		color: {
			default: null,
			":disabled": "oklch(70.5% 0.015 286.067)",
			"@media (prefers-color-scheme: dark)": { default: null, ":disabled": "oklch(44.2% 0.017 285.786)" },
		},
	},
	pausedRow: {
		display: "flex",
		flexDirection: "column",
		alignItems: "flex-end",
	},
	pausedControls: {
		display: "flex",
		alignItems: "center",
		gap: "0.5rem",
	},
	/**
	 * Amber as standalone text on the app ground, not inside a warning banner, so
	 * the `warn*` tokens — tuned against `warnSurface` — do not apply here.
	 */
	pausedLabel: {
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
		color: {
			default: "oklch(55.5% 0.163 48.998)",
			"@media (prefers-color-scheme: dark)": "oklch(82.8% 0.189 84.429)",
		},
	},
	anchor: {
		position: "relative",
	},
	menu: {
		position: "absolute",
		right: 0,
		top: "100%",
		zIndex: 10,
		marginTop: "0.25rem",
		display: "flex",
		width: "9rem",
		flexDirection: "column",
		borderRadius: "0.25rem",
		borderWidth: 1,
		borderStyle: "solid",
		borderColor: colors.border,
		backgroundColor: colors.surfaceRaised,
		paddingBlock: "0.25rem",
		boxShadow: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
	},
	menuItem: {
		borderStyle: "none",
		backgroundColor: { default: "transparent", ":hover": colors.surfaceHover },
		color: "inherit",
		paddingInline: "0.75rem",
		paddingBlock: "0.375rem",
		textAlign: "left",
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
	},
});

export function formatRemaining(totalSeconds: number): string {
	const clamped = Math.max(0, totalSeconds);
	const hours = Math.floor(clamped / 3600);
	const minutes = Math.floor((clamped % 3600) / 60);
	const seconds = clamped % 60;
	const pad = (n: number) => String(n).padStart(2, "0");
	return hours > 0 ? `${hours}:${pad(minutes)}:${pad(seconds)}` : `${minutes}:${pad(seconds)}`;
}

function nowSeconds(): number {
	return Math.floor(Date.now() / 1000);
}

function useNowSeconds(active: boolean): number {
	const [now, setNow] = useState(nowSeconds);
	useEffect(() => {
		if (!active) return;
		setNow(nowSeconds());
		const id = setInterval(() => setNow(nowSeconds()), 1000);
		return () => clearInterval(id);
	}, [active]);
	return now;
}

export default function PauseWidget() {
	const queryClient = useQueryClient();
	const { data } = useQuery({
		...pauseQuery(),
		refetchInterval: (query) => (query.state.data?.paused === true ? 5000 : false),
	});
	const mutation = useMutation(pauseMutation(queryClient));
	const [menuOpen, setMenuOpen] = useState(false);
	const now = useNowSeconds(data?.paused === true && data.until !== null);
	const paused = data?.paused === true;
	const { reset } = mutation;
	useEffect(() => reset(), [paused, reset]);

	if (data === undefined) {
		return (
			<button type="button" disabled {...stylex.props(shared.button, styles.trigger, shared.focusRing)}>
				Pause
			</button>
		);
	}

	if (data.paused) {
		return (
			<div {...stylex.props(styles.pausedRow)}>
				<div {...stylex.props(styles.pausedControls)}>
					<span {...stylex.props(styles.pausedLabel)}>
						{data.until === null ? "Paused" : `Paused ${formatRemaining(data.until - now)}`}
					</span>
					<button
						type="button"
						onClick={() => mutation.mutate({ paused: false })}
						disabled={mutation.isPending}
						{...stylex.props(shared.button, styles.trigger, shared.focusRing)}
					>
						Resume
					</button>
				</div>
				<InlineError error={mutation.error} />
			</div>
		);
	}

	return (
		<div
			{...stylex.props(styles.anchor)}
			onKeyDown={(e) => {
				if (e.key === "Escape") setMenuOpen(false);
			}}
		>
			<button
				type="button"
				aria-expanded={menuOpen}
				aria-controls="pause-menu"
				onClick={() => setMenuOpen((open) => !open)}
				disabled={mutation.isPending}
				{...stylex.props(shared.button, styles.trigger, shared.focusRing)}
			>
				Pause
			</button>
			{menuOpen && (
				<div id="pause-menu" {...stylex.props(styles.menu)}>
					{DURATIONS.map(({ label, seconds }) => (
						<button
							key={label}
							type="button"
							onClick={() => {
								setMenuOpen(false);
								mutation.mutate(
									seconds === null ? { paused: true } : { paused: true, duration_seconds: seconds },
								);
							}}
							{...stylex.props(styles.menuItem, shared.insetFocusRing)}
						>
							{label}
						</button>
					))}
				</div>
			)}
			<InlineError error={mutation.error} />
		</div>
	);
}
