import { useEffect, useCallback, useState, useRef } from 'react'; import { useDispatch } from 'react-redux'; import { useAppSelector } from '@akinon/next/redux/hooks'; import { setScriptLoaded } from '../redux/reducer'; import { initMasterpass } from '../utils/masterpass-sdk'; import type { MasterpassEnvironment } from '../utils/constants'; interface UseMasterpassScriptProps { scriptUrl?: string; sdkUrl?: string; environment?: MasterpassEnvironment; locale?: string; onScriptLoaded?: () => void; onScriptError?: (error: Error) => void; } export const useMasterpassScript = ({ scriptUrl = '/masterpass-javascript-sdk-web.min.js', sdkUrl, environment, locale = 'en', onScriptLoaded, onScriptError }: UseMasterpassScriptProps = {}) => { const dispatch = useDispatch(); const { isScriptLoaded } = useAppSelector((state) => state.masterpassRest); const [isMasterpassInitialized, setIsMasterpassInitialized] = useState(false); const hasInitialized = useRef(false); const currentLocale = useRef(locale); const callbackFired = useRef(false); const stableOnScriptLoaded = useCallback(() => { if (!callbackFired.current) { callbackFired.current = true; onScriptLoaded?.(); } }, [onScriptLoaded]); const stableOnScriptError = useCallback( (error: Error) => { onScriptError?.(error); }, [onScriptError] ); const initializeMasterpassSDK = useCallback((localeValue: string) => { if (hasInitialized.current && currentLocale.current === localeValue) { return; } const attemptInit = () => { try { initMasterpass({ language: localeValue, endpoint: sdkUrl, environment }); setIsMasterpassInitialized(true); hasInitialized.current = true; currentLocale.current = localeValue; } catch (error) { console.error('Failed to initialize Masterpass SDK:', error); } }; if (window.Masterpass) { attemptInit(); } else { setTimeout(() => { if (window.Masterpass) { attemptInit(); } else { console.error('Masterpass SDK still not available after delay'); } }, 100); } }, [sdkUrl, environment]); const loadScript = useCallback(() => { if ( isScriptLoaded || document.querySelector(`script[src="${scriptUrl}"]`) ) { dispatch(setScriptLoaded(true)); if (!hasInitialized.current || currentLocale.current !== locale) { initializeMasterpassSDK(locale); } stableOnScriptLoaded(); return; } const script = document.createElement('script'); script.src = scriptUrl; script.async = true; script.defer = true; script.onload = () => { dispatch(setScriptLoaded(true)); initializeMasterpassSDK(locale); stableOnScriptLoaded(); }; script.onerror = (error) => { const scriptError = new Error( `Failed to load Masterpass script from ${scriptUrl}` ); console.error('Masterpass script loading error:', scriptError); stableOnScriptError(scriptError); }; document.head.appendChild(script); }, [scriptUrl, isScriptLoaded, dispatch, locale, initializeMasterpassSDK]); const unloadScript = useCallback(() => { const existingScript = document.querySelector(`script[src="${scriptUrl}"]`); if (existingScript) { existingScript.remove(); } dispatch(setScriptLoaded(false)); setIsMasterpassInitialized(false); hasInitialized.current = false; }, [scriptUrl, dispatch]); useEffect(() => { loadScript(); }, [scriptUrl, isScriptLoaded]); useEffect(() => { if ( isScriptLoaded && hasInitialized.current && currentLocale.current !== locale ) { initializeMasterpassSDK(locale); } }, [locale, isScriptLoaded, initializeMasterpassSDK]); return { isScriptLoaded, loadScript, unloadScript, isMasterpassInitialized }; };