"use client";

import Script from "next/script";
import { useCallback, useRef } from "react";

/**
 * Cloudflare Turnstile challenge for the public forms.
 *
 * Renders nothing unless `NEXT_PUBLIC_TURNSTILE_SITE_KEY` is set, so the site
 * behaves exactly as before until keys are configured.
 *
 * The widget injects a hidden `cf-turnstile-response` input into the
 * surrounding <form>. Both forms build their payload with
 * `Object.fromEntries(new FormData(form))`, so the token is picked up without
 * either of them having to know about it. The server verifies it in
 * app/lib/turnstile.ts — the widget alone proves nothing, since the API routes
 * accept direct POSTs.
 *
 * Rendering is explicit rather than Turnstile's automatic class scan: the scan
 * runs once when the script loads, which races React and silently no-ops if
 * the component mounts afterwards.
 */

declare global {
  interface Window {
    turnstile?: {
      render: (
        element: HTMLElement,
        options: { sitekey: string; theme?: "light" | "dark" | "auto" }
      ) => string | undefined;
    };
  }
}

const SITE_KEY = process.env.NEXT_PUBLIC_TURNSTILE_SITE_KEY;

export function TurnstileWidget() {
  const containerRef = useRef<HTMLDivElement>(null);
  const hasRendered = useRef(false);

  const renderWidget = useCallback(() => {
    if (hasRendered.current || !containerRef.current || !window.turnstile) return;
    hasRendered.current = true;
    window.turnstile.render(containerRef.current, {
      sitekey: SITE_KEY!,
      theme: "auto",
    });
  }, []);

  if (!SITE_KEY) return null;

  return (
    <>
      <Script
        src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit"
        strategy="afterInteractive"
        onReady={renderWidget}
      />
      <div ref={containerRef} className="turnstile-widget" />
    </>
  );
}
