import { useCallback, useEffect, useImperativeHandle, useRef, forwardRef } from "react";

const SCRIPT_ID = "cf-turnstile-script";
const SCRIPT_SRC = "https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit";

function ensureScript(onReady) {
  if (typeof window === "undefined") return;
  const existing = document.getElementById(SCRIPT_ID);
  if (existing) {
    if (window.turnstile) {
      onReady();
    } else {
      existing.addEventListener("load", onReady, { once: true });
    }
    return;
  }
  const s = document.createElement("script");
  s.id = SCRIPT_ID;
  s.src = SCRIPT_SRC;
  s.defer = true;
  s.addEventListener("load", onReady, { once: true });
  document.head.appendChild(s);
}

/**
 * Cloudflare Turnstile 人机验证组件。
 * 通过 ref.reset() 可在提交后重置 widget 以获取新 token。
 *
 * @param {string}   siteKey   - Cloudflare Turnstile Site Key
 * @param {Function} onToken   - token 回调（token 失效/错误时传入空串）
 * @param {"light"|"dark"|"auto"} [theme]
 */
const TurnstileWidget = forwardRef(function TurnstileWidget(
  { siteKey, onToken, theme = "light" },
  ref
) {
  const containerRef = useRef(null);
  const widgetIdRef = useRef(null);
  const onTokenRef = useRef(onToken);

  useEffect(() => { onTokenRef.current = onToken; }, [onToken]);

  const removeWidget = useCallback(() => {
    if (widgetIdRef.current != null && window.turnstile) {
      try { window.turnstile.remove(widgetIdRef.current); } catch {}
      widgetIdRef.current = null;
    }
    if (containerRef.current) containerRef.current.innerHTML = "";
  }, []);

  const renderWidget = useCallback(() => {
    if (!containerRef.current || !window.turnstile) return;
    removeWidget();
    widgetIdRef.current = window.turnstile.render(containerRef.current, {
      sitekey: siteKey,
      theme,
      callback: (token) => onTokenRef.current?.(token),
      "expired-callback": () => onTokenRef.current?.(""),
      "error-callback": () => onTokenRef.current?.(""),
    });
  }, [siteKey, theme, removeWidget]);

  useImperativeHandle(ref, () => ({
    reset() {
      if (widgetIdRef.current != null && window.turnstile) {
        try { window.turnstile.reset(widgetIdRef.current); } catch {}
      }
    },
  }));

  useEffect(() => {
    ensureScript(renderWidget);
    return removeWidget;
  }, [renderWidget, removeWidget]);

  return <div ref={containerRef} className="turnstile-widget" />;
});

export default TurnstileWidget;
