import { useEffect, useRef, useState } from "react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";

interface QrScannerProps {
	onScan: (token: string) => void;
	onCancel: () => void;
}

export function QrScanner({ onScan, onCancel }: QrScannerProps) {
	const scannerDivId = "qr-reader-container";
	const scannerRef = useRef<unknown>(null);
	const [hasError, setHasError] = useState(false);
	const [manualToken, setManualToken] = useState("");
	// Keep a stable ref to onScan so the effect never re-runs due to identity changes
	const onScanRef = useRef(onScan);
	useEffect(() => {
		onScanRef.current = onScan;
	}, [onScan]);

	useEffect(() => {
		let stopped = false;

		import("html5-qrcode")
			.then(({ Html5QrcodeScanner }) => {
				if (stopped) return;

				const scanner = new Html5QrcodeScanner(
					scannerDivId,
					{
						fps: 10,
						qrbox: { width: 250, height: 250 },
					},
					false,
				);

				scannerRef.current = scanner;

				scanner.render(
					(decodedText: string) => {
						scanner.clear().catch(console.error);
						onScanRef.current(decodedText);
					},
					(error: string) => {
						// Suppress routine "not found" scan errors
						if (!error.includes("No QR code found")) {
							console.debug("QR scan error:", error);
						}
					},
				);
			})
			.catch((err) => {
				console.error("Failed to load html5-qrcode:", err);
				setHasError(true);
			});

		return () => {
			stopped = true;
			if (scannerRef.current) {
				(scannerRef.current as { clear: () => Promise<void> })
					.clear()
					.catch(console.error);
			}
		};
	}, []); // empty deps — runs once on mount, cleans up on unmount

	const handleManualSubmit = () => {
		const token = manualToken.trim();
		if (token) {
			onScan(token);
		}
	};

	return (
		<div className="space-y-4">
			{!hasError ? (
				<div id={scannerDivId} className="overflow-hidden rounded-xl" />
			) : (
				<div className="rounded-xl border border-white/10 bg-white/5 p-4 text-center">
					<p className="mb-2 text-sm text-white/60">
						Camera niet beschikbaar. Plak het QR-token hieronder.
					</p>
				</div>
			)}

			{/* Manual fallback */}
			<div>
				<p className="mb-2 text-white/40 text-xs">Of plak token handmatig:</p>
				<div className="flex gap-2">
					<Input
						value={manualToken}
						onChange={(e) => setManualToken(e.target.value)}
						placeholder="QR token..."
						className="border-white/20 bg-white/10 text-white placeholder:text-white/30"
						onKeyDown={(e) => e.key === "Enter" && handleManualSubmit()}
					/>
					<Button
						onClick={handleManualSubmit}
						disabled={!manualToken.trim()}
						className="bg-white text-[#214e51] hover:bg-white/90"
					>
						OK
					</Button>
				</div>
			</div>

			<Button
				onClick={onCancel}
				variant="outline"
				className="w-full border-white/20 bg-transparent text-white hover:bg-white/10"
			>
				Annuleren
			</Button>
		</div>
	);
}
