import { useEffect, useRef, useState } from 'react';

declare global {
    interface Window {
        grecaptcha: {
            ready: (callback: () => void) => void;
            execute: (siteKey: string, options: { action: string }) => Promise<string>;
        };
        turnstile: {
            render: (container: HTMLElement, options: {
                sitekey: string;
                callback: (token: string) => void;
                'expired-callback'?: () => void;
                'error-callback'?: () => void;
                theme?: 'light' | 'dark' | 'auto';
                size?: 'normal' | 'compact' | 'invisible';
                appearance?: 'always' | 'execute' | 'interaction-only';
            }) => string;
            reset: (widgetId: string) => void;
            execute: (container: HTMLElement | string) => void;
            remove: (widgetId: string) => void;
        };
    }
}

interface CaptchaWidgetProps {
    provider: 'none' | 'recaptcha' | 'turnstile';
    siteKey: string;
    onToken: (token: string) => void;
    action?: string; // for reCAPTCHA v3 action name
}

/**
 * Invisible CAPTCHA widget for checkout
 * Supports Google reCAPTCHA v3 and Cloudflare Turnstile
 */
export function CaptchaWidget({ provider, siteKey, onToken, action = 'checkout' }: CaptchaWidgetProps) {
    const containerRef = useRef<HTMLDivElement>(null);
    const widgetIdRef = useRef<string | null>(null);
    const [isLoaded, setIsLoaded] = useState(false);

    useEffect(() => {
        if (provider === 'none' || !siteKey) {
            return;
        }

        // Load the appropriate script
        const loadScript = (src: string, id: string): Promise<void> => {
            return new Promise((resolve, reject) => {
                if (document.getElementById(id)) {
                    resolve();
                    return;
                }
                const script = document.createElement('script');
                script.id = id;
                script.src = src;
                script.async = true;
                script.defer = true;
                script.onload = () => resolve();
                script.onerror = () => reject(new Error(`Failed to load ${id}`));
                document.head.appendChild(script);
            });
        };

        const initCaptcha = async () => {
            try {
                if (provider === 'recaptcha') {
                    await loadScript(
                        `https://www.google.com/recaptcha/api.js?render=${siteKey}`,
                        'recaptcha-script'
                    );

                    // Wait for grecaptcha to be ready
                    window.grecaptcha.ready(() => {
                        setIsLoaded(true);
                    });
                } else if (provider === 'turnstile') {
                    await loadScript(
                        'https://challenges.cloudflare.com/turnstile/v0/api.js',
                        'turnstile-script'
                    );

                    // Wait a bit for turnstile to initialize
                    setTimeout(() => {
                        if (containerRef.current && window.turnstile) {
                            widgetIdRef.current = window.turnstile.render(containerRef.current, {
                                sitekey: siteKey,
                                callback: (token: string) => {
                                    onToken(token);
                                },
                                'expired-callback': () => {
                                    onToken('');
                                },
                                'error-callback': () => {
                                    onToken('');
                                },
                                appearance: 'interaction-only',
                                size: 'invisible',
                            });
                            setIsLoaded(true);
                        }
                    }, 100);
                }
            } catch (error) {
                console.error('Failed to load CAPTCHA:', error);
            }
        };

        initCaptcha();

        // Cleanup
        return () => {
            if (provider === 'turnstile' && widgetIdRef.current && window.turnstile) {
                try {
                    window.turnstile.remove(widgetIdRef.current);
                } catch {
                    // Ignore errors during cleanup
                }
            }
        };
    }, [provider, siteKey, onToken]);

    // Execute reCAPTCHA when loaded
    useEffect(() => {
        if (provider === 'recaptcha' && isLoaded && window.grecaptcha) {
            const executeRecaptcha = async () => {
                try {
                    const token = await window.grecaptcha.execute(siteKey, { action });
                    onToken(token);
                } catch (error) {
                    console.error('reCAPTCHA execute failed:', error);
                    onToken('');
                }
            };

            // Execute immediately and then every 2 minutes (tokens expire)
            executeRecaptcha();
            const interval = setInterval(executeRecaptcha, 2 * 60 * 1000);

            return () => clearInterval(interval);
        }
    }, [provider, isLoaded, siteKey, action, onToken]);

    // Render nothing visible - both are invisible modes
    if (provider === 'none' || !siteKey) {
        return null;
    }

    return (
        <div
            ref={containerRef}
            className="captcha-widget"
            style={{
                position: 'absolute',
                visibility: 'hidden',
                width: 0,
                height: 0,
                overflow: 'hidden',
            }}
        />
    );
}

export default CaptchaWidget;
