"use client";

import { useEffect, useRef } from "react";
import Script from "next/script";
import { cn } from "@/lib/utils";

declare global {
  interface Window {
    turnstile?: {
      render: (el: HTMLElement | string, opts: Record<string, unknown>) => string;
      remove: (id: string) => void;
      reset: (id?: string) => void;
    };
    onTurnstileLoad?: () => void;
  }
}

// Le `?onload=onTurnstileLoad` permet d'avoir un callback global appele des
// que le script est pret. Cle pour eviter les races entre mount React et
// chargement script.
const TURNSTILE_SRC =
  "https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onTurnstileLoad";

type Props = {
  /** Site key publique Cloudflare Turnstile. Si non fournie : composant rend null. */
  siteKey?: string;
  /** Theme du widget. 'auto' s'adapte au color-scheme. */
  theme?: "light" | "dark" | "auto";
  /** Action label pour analytics Turnstile (optionnel). */
  action?: string;
  className?: string;
};

/**
 * Widget Cloudflare Turnstile (anti-bot CAPTCHA, mode Managed = la plupart du
 * temps invisible, parfois checkbox interactive si le score de risque le justifie).
 *
 * Le widget populate automatiquement un input cache nomme `cf-turnstile-response`
 * dans le form parent, qui est ensuite valide cote serveur via verifyTurnstileToken.
 *
 * Comportement gracieux : si NEXT_PUBLIC_TURNSTILE_SITE_KEY n'est pas defini,
 * le composant rend null et la verification serveur est skipped (dev local).
 *
 * Rendu : la classe `cf-turnstile` declenche l'auto-render du script Cloudflare
 * a son load. En backup, useEffect appelle explicitement window.turnstile.render
 * via le callback global `onTurnstileLoad` si le script est deja la.
 */
export function TurnstileWidget({
  siteKey = process.env.NEXT_PUBLIC_TURNSTILE_SITE_KEY,
  theme = "light",
  action,
  className,
}: Props) {
  const containerRef = useRef<HTMLDivElement>(null);
  const widgetIdRef = useRef<string | null>(null);

  useEffect(() => {
    if (!siteKey || !containerRef.current) return;

    const render = () => {
      if (!window.turnstile || !containerRef.current || widgetIdRef.current) return;
      widgetIdRef.current = window.turnstile.render(containerRef.current, {
        sitekey: siteKey,
        theme,
        action,
      });
    };

    // Le script est deja la (cas hot reload, ou widget re-mount) : render direct.
    if (window.turnstile) {
      render();
    } else {
      // Sinon on attend le callback global du script. La query ?onload=
      // garantit que le script l'appelera une seule fois quand il est pret.
      window.onTurnstileLoad = render;
    }

    return () => {
      if (widgetIdRef.current && window.turnstile) {
        try {
          window.turnstile.remove(widgetIdRef.current);
        } catch {
          // widget deja remove
        }
        widgetIdRef.current = null;
      }
    };
  }, [siteKey, theme, action]);

  if (!siteKey) return null;

  return (
    <>
      <Script src={TURNSTILE_SRC} strategy="afterInteractive" />
      {/* Classe `cf-turnstile` indispensable pour l'auto-scan du script
          Cloudflare. data-* sont des fallbacks si l'auto-render se declenche
          avant le useEffect. */}
      <div
        ref={containerRef}
        className={cn("cf-turnstile", className)}
        data-sitekey={siteKey}
        data-theme={theme}
        data-action={action}
      />
    </>
  );
}
