let googleClient = null; let isSigningIn = false; function waitForGoogleApi() { return new Promise((resolve, reject) => { if (window.google?.accounts?.oauth2) { resolve(window.google); return; } const maxAttempts = 20; let attempts = 0; const checkGoogle = setInterval(() => { attempts++; if (window.google?.accounts?.oauth2) { clearInterval(checkGoogle); resolve(window.google); } else if (attempts >= maxAttempts) { clearInterval(checkGoogle); reject(new Error('Google OAuth2 API failed to load within the timeout period')); } }, 100); }); } async function handleAuthError(error, context = '') { const errorMessage = error?.message || error?.type || error?.toString() || 'Unknown error'; const fullError = `${context}: ${errorMessage}`; console.error('Google Auth Error:', { context, error, fullError }); await DotNet.invokeMethodAsync('Bimix.UI.Shared', 'OnGoogleSignInError', fullError); } async function fetchUserInfo(accessToken) { const response = await fetch('https://www.googleapis.com/oauth2/v3/userinfo', { headers: { 'Authorization': `Bearer ${accessToken}` } }); if (!response.ok) { const errorText = await response.text(); console.error('Failed to fetch user info:', errorText); await DotNet.invokeMethodAsync('Bimix.UI.Shared', 'OnGoogleSignInError', `Failed to fetch user info: HTTP ${response.status}`); return null; } return await response.json(); } window.initGoogleSignIn = async function(clientId) { if (googleClient) { return googleClient; } try { const google = await waitForGoogleApi(); googleClient = google.accounts.oauth2.initTokenClient({ client_id: clientId, scope: 'email profile', callback: async (tokenResponse) => { try { if (tokenResponse.error) { console.error('Token response error:', tokenResponse.error); await DotNet.invokeMethodAsync('Bimix.UI.Shared', 'OnGoogleSignInError', tokenResponse.error); return; } const userInfo = await fetchUserInfo(tokenResponse.access_token); if (!userInfo) return; await DotNet.invokeMethodAsync('Bimix.UI.Shared', 'OnGoogleSignInSuccess', tokenResponse.access_token, userInfo.name || '', userInfo.email || '', userInfo.picture || '' ); } catch (error) { console.error('Callback error:', error); await DotNet.invokeMethodAsync('Bimix.UI.Shared', 'OnGoogleSignInError', error.message || 'Unknown callback error'); } finally { isSigningIn = false; } }, error_callback: async (error) => { console.error('OAuth flow error:', error); await DotNet.invokeMethodAsync('Bimix.UI.Shared', 'OnGoogleSignInError', error.type || 'OAuth flow error'); isSigningIn = false; } }); return googleClient; } catch (error) { console.error('Initiaxcrun xctrace list deviceslization error:', error); await DotNet.invokeMethodAsync('Bimix.UI.Shared', 'OnGoogleSignInError', error.message || 'Failed to initialize Google Sign-In'); isSigningIn = false; } }; window.requestGoogleSignIn = async function() { if (isSigningIn) { console.log('Sign-in already in progress'); return; } if (!googleClient) { console.error('Google Sign-In not initialized'); await DotNet.invokeMethodAsync('Bimix.UI.Shared', 'OnGoogleSignInError', 'Google Sign-In not initialized. Call initGoogleSignIn first.'); return; } isSigningIn = true; googleClient.requestAccessToken(); };