import { useQuery } from "@tanstack/react-query";
import { useEffect, useRef, useState } from "react";
import { orpc } from "@/utils/orpc";

interface QrCodeCanvasProps {
	token: string;
}

function QrCodeCanvas({ token }: QrCodeCanvasProps) {
	const canvasRef = useRef<HTMLCanvasElement>(null);

	useEffect(() => {
		if (!canvasRef.current || !token) return;
		// Dynamic import to avoid SSR issues
		import("qrcode").then((QRCode) => {
			if (canvasRef.current) {
				QRCode.toCanvas(canvasRef.current, token, {
					width: 280,
					margin: 2,
					color: { dark: "#214e51", light: "#ffffff" },
				});
			}
		});
	}, [token]);

	return <canvas ref={canvasRef} className="rounded-xl" />;
}

function useCountdown(expiresAt: Date | undefined) {
	const [secondsLeft, setSecondsLeft] = useState<number>(0);

	useEffect(() => {
		if (!expiresAt) return;

		const tick = () => {
			const diff = Math.max(
				0,
				Math.floor((expiresAt.getTime() - Date.now()) / 1000),
			);
			setSecondsLeft(diff);
		};

		tick();
		const interval = setInterval(tick, 1000);
		return () => clearInterval(interval);
	}, [expiresAt]);

	return secondsLeft;
}

export function QrCodeDisplay() {
	const { data, refetch, isLoading, isError } = useQuery(
		orpc.drinkkaart.getMyQrToken.queryOptions(),
	);

	const expiresAt = data?.expiresAt ? new Date(data.expiresAt) : undefined;
	const secondsLeft = useCountdown(expiresAt);

	// Auto-refresh 60s before expiry
	useEffect(() => {
		if (!expiresAt) return;
		const refreshAt = expiresAt.getTime() - 60_000;
		const delay = refreshAt - Date.now();
		if (delay <= 0) {
			refetch();
			return;
		}
		const timer = setTimeout(() => refetch(), delay);
		return () => clearTimeout(timer);
	}, [expiresAt, refetch]);

	// Refresh on tab focus if token is about to expire
	useEffect(() => {
		const onVisibility = () => {
			if (document.visibilityState === "visible" && expiresAt) {
				if (Date.now() >= expiresAt.getTime() - 10_000) refetch();
			}
		};
		document.addEventListener("visibilitychange", onVisibility);
		return () => document.removeEventListener("visibilitychange", onVisibility);
	}, [expiresAt, refetch]);

	const minutes = Math.floor(secondsLeft / 60);
	const seconds = secondsLeft % 60;
	const countdownLabel = `${minutes}:${String(seconds).padStart(2, "0")}`;

	if (isLoading) {
		return (
			<div className="flex h-[280px] w-[280px] items-center justify-center rounded-xl bg-white/10">
				<div className="h-8 w-8 animate-spin rounded-full border-2 border-white/20 border-t-white" />
			</div>
		);
	}

	if (isError || !data?.token) {
		return (
			<div className="flex h-[280px] w-[280px] flex-col items-center justify-center gap-2 rounded-xl bg-white/10">
				<p className="text-sm text-white/60">Kon QR-code niet laden</p>
				<button
					type="button"
					onClick={() => refetch()}
					className="text-sm text-white underline"
				>
					Opnieuw proberen
				</button>
			</div>
		);
	}

	return (
		<div className="flex flex-col items-center gap-3">
			<div className="rounded-xl bg-white p-3 shadow-lg">
				<QrCodeCanvas token={data.token} />
			</div>
			<p className="text-sm text-white/60">
				{secondsLeft > 0 ? (
					<>
						Vervalt over{" "}
						<span className="text-white/80 tabular-nums">{countdownLabel}</span>
					</>
				) : (
					<span className="text-yellow-400">Verlopen — vernieuwen...</span>
				)}
			</p>
		</div>
	);
}
