// Lalaluxe booking — components/ConsentModal.jsx (split from app.jsx; load before app.jsx — see CLAUDE.md "multi-file Babel contract")
function ConsentModal({ s, sq, busy, error, onToggle, onCancel, onConfirm }) {
	const charge = dueNow(s);
	// SQUARE BYPASS — no charge happens under bypass; gates every payment promise below (docs/REMOVING-SQUARE-BYPASS.md)
	const bypass = !!(sq && sq.bypass);
	const cardRef = useRef(null);
	// Modal contract (mounted only while open — app.jsx renders this conditionally):
	// move focus onto the card so the title announces, lock the page scroller behind
	// the scrim, restore both on close. Mirrors the intro lightbox (intro.jsx).
	useEffect(() => {
		const opener = document.activeElement;
		cardRef.current && cardRef.current.focus();
		const wrap = document.querySelector(".screen-wrap");
		const prevOverflow = wrap ? wrap.style.overflowY : "";
		if (wrap) wrap.style.overflowY = "hidden";
		return () => {
			if (wrap) wrap.style.overflowY = prevOverflow;
			opener && opener.focus && opener.focus();
		};
	}, []);
	// Escape cancels (same busy guard as the Cancel button) — window-level like the
	// intro lightbox, so it works wherever focus sits.
	useEffect(() => {
		const onKey = (e) => {
			if (e.key === "Escape" && !busy) onCancel();
		};
		window.addEventListener("keydown", onKey);
		return () => window.removeEventListener("keydown", onKey);
	}, [busy, onCancel]);
	// Tab is trapped inside the card. Enabled controls only — the confirm CTA is
	// disabled until the box is checked and focus() on a disabled element is a
	// silent no-op that would leak focus out.
	const onKeyDown = (e) => {
		if (e.key !== "Tab") return;
		const f = cardRef.current.querySelectorAll(
			"button:not(:disabled), input:not(:disabled)",
		);
		if (!f.length) return;
		const first = f[0],
			last = f[f.length - 1];
		if (
			e.shiftKey &&
			(document.activeElement === first ||
				document.activeElement === cardRef.current)
		) {
			e.preventDefault();
			last.focus();
		} else if (!e.shiftKey && document.activeElement === last) {
			e.preventDefault();
			first.focus();
		}
	};
	return (
		<div
			className="modal-scrim"
			onClick={(e) => {
				if (e.target.classList.contains("modal-scrim")) onCancel();
			}}
		>
			<div
				className="modal-card"
				role="dialog"
				aria-modal="true"
				aria-labelledby="consent-title"
				ref={cardRef}
				tabIndex={-1}
				onKeyDown={onKeyDown}
			>
				<span
					className="deco-spark"
					style={{ top: 14, right: 16, width: 12, height: 12 }}
				></span>
				<span
					className="deco-spark"
					style={{ bottom: 16, left: 18, width: 9, height: 9, opacity: 0.6 }}
				></span>

				<h3 className="modal-title" id="consent-title">
					{/* SQUARE BYPASS — restore the static "you pay" when removing */}
					Before <em>{bypass ? "you book" : "you pay"}</em>.
				</h3>

				<div className="modal-stmt">
					{/* SQUARE BYPASS — restore the unconditional statement preview when removing */}
					{bypass ? (
						<div className="stmt-label">
							Online payment is temporarily off — no charge today. Your $
							{charge}{" "}
							{s.visit === "subscription" ? "plan total" : "deposit"} is due at
							your visit.
						</div>
					) : (
						<>
							<div className="stmt-label">
								Here&apos;s what transactions will look like on your bank/card
								statement:
							</div>
							<div className="stmt-preview">
								<span className="stmt-name">LALA LUXE</span>
								<span className="stmt-dash"></span>
								<span className="stmt-amt">${charge}.00</span>
							</div>
						</>
					)}
				</div>

				<div className="modal-policy">
					<div className="policy-label">Cancellation &amp; reschedule</div>
					<p className="policy-body">
						Your ${charge} deposit is non-refundable for any cancellation or
						reschedule made within <strong>24 hours</strong> of your
						appointment.
					</p>
				</div>

				<label className="consent-check">
					<input type="checkbox" checked={s.acknowledged} onChange={onToggle} />
					<span className="cbox">
						<span className="check"></span>
					</span>
					<span className="ctxt">{ACK_TEXT}</span>
				</label>

				{error && (
					<div className="modal-error" role="alert" style={{ marginTop: 4 }}>
						{error}
					</div>
				)}

				<div className="modal-actions">
					<button className="modal-cancel" onClick={onCancel} disabled={busy}>
						Cancel
					</button>
					<button
						className="cta cherry"
						disabled={!s.acknowledged || busy}
						onClick={onConfirm}
						style={{ flex: 1 }}
					>
						{/* SQUARE BYPASS — restore the Square button labels when removing */}
						{busy ? (
							bypass ? "Booking…" : "Opening Square…"
						) : (
							<>
								{bypass ? "Confirm booking" : "Continue to Square"}{" "}
								<span className="arrow"></span>
							</>
						)}
					</button>
				</div>
			</div>
		</div>
	);
}

/* ============== Mount ============== */
