"use client";

import { useEffect, useRef } from "react";

declare global {
  interface Window {
    turnstile?: {
      render: (
        container: HTMLElement,
        options: {
          sitekey: string;
          theme?: "light" | "dark" | "auto";
          appearance?: "always" | "execute" | "interaction-only";
          execution?: "render" | "execute";
          callback?: (token: string) => void;
          "expired-callback"?: () => void;
          "error-callback"?: () => void;
        },
      ) => string;
      execute?: (widgetId: string) => void;
      reset: (widgetId: string) => void;
      remove: (widgetId: string) => void;
    };
  }
}

const SITE_KEY = process.env.NEXT_PUBLIC_TURNSTILE_SITE_KEY;
const DEV_BYPASS_TOKEN = "turnstile-dev-bypass";
const SCRIPT_SRC = "https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit";

function ensureTurnstileScript(): void {
  const existing = document.querySelector<HTMLScriptElement>('script[data-covalba-turnstile="true"]');
  if (existing) return;

  const script = document.createElement("script");
  script.src = SCRIPT_SRC;
  script.async = true;
  script.defer = true;
  script.dataset.covalbaTurnstile = "true";
  document.head.appendChild(script);
}

export function TurnstileCaptcha({
  onToken,
  theme = "light",
}: {
  onToken: (token: string) => void;
  theme?: "light" | "dark" | "auto";
}) {
  const containerRef = useRef<HTMLDivElement>(null);
  const widgetIdRef = useRef<string | null>(null);

  useEffect(() => {
    if (!SITE_KEY) {
      if (process.env.NODE_ENV !== "production") onToken(DEV_BYPASS_TOKEN);
      return;
    }

    let cancelled = false;

    ensureTurnstileScript();

    const executeWidget = () => {
      const widgetId = widgetIdRef.current;
      if (widgetId && window.turnstile?.execute) {
        window.turnstile.execute(widgetId);
      }
    };

    const renderInterval = window.setInterval(() => {
      if (cancelled || widgetIdRef.current) return;
      if (!containerRef.current || !window.turnstile?.render) return;

      try {
        if (cancelled || !containerRef.current || !window.turnstile || widgetIdRef.current) return;
        widgetIdRef.current = window.turnstile.render(containerRef.current, {
          sitekey: SITE_KEY,
          theme,
          appearance: "always",
          execution: "execute",
          callback: onToken,
          "expired-callback": () => {
            onToken("");
            executeWidget();
          },
          "error-callback": () => onToken(""),
        });
        executeWidget();
        if (renderInterval) window.clearInterval(renderInterval);
      } catch {
        onToken("");
      }
    }, 50);

    const timeout = window.setTimeout(() => {
      if (!widgetIdRef.current) onToken("");
      if (renderInterval) window.clearInterval(renderInterval);
    }, 15_000);

    return () => {
      cancelled = true;
      if (renderInterval) window.clearInterval(renderInterval);
      if (timeout) window.clearTimeout(timeout);
      if (widgetIdRef.current && window.turnstile) {
        window.turnstile.remove(widgetIdRef.current);
        widgetIdRef.current = null;
      }
    };
  }, [onToken, theme]);

  if (!SITE_KEY && process.env.NODE_ENV !== "production") return null;

  return <div ref={containerRef} className="min-h-[65px]" />;
}
