mergeInto(LibraryManager.library, {
  // ═══════════════════════════════════════════════════════════════
  // COMMUNICATION IFRAME via window.postMessage
  // Entre Unity WebGL et le site parent
  // ═══════════════════════════════════════════════════════════════
  
  $UJSA_EarlyInit__postset: `
    (function() {
      var inIframe = window.self !== window.top;
      
      if (!inIframe) {
        window.UJSA_InIframe = false;
        return;
      }
      
      window.UJSA_InIframe = true;
      window.UJSA_JWT = null;
      window.UJSA_SLUG = null;
      
      // LISTE DES ORIGINES AUTORISÉES (production + recette + dev)
      window.UJSA_ALLOWED_ORIGINS = [
        'https://www.newsassurancespro.com',
        'https://newsassurancespro.com',
        'https://ujsa.studioplc.fr',
        'https://studioplc.fr',
        'https://www.studioplc.fr',
        'http://localhost:3000',
        'http://localhost:8080',
        'http://127.0.0.1:3000',
        'http://127.0.0.1:8080',
        'http://localhost',
        'http://127.0.0.1'
      ];
      window.UJSA_PARENT_ORIGIN = null;
      
      window.UJSA_IsOriginAllowed = function(origin) {
        return window.UJSA_ALLOWED_ORIGINS.indexOf(origin) !== -1;
      };
      
      if (!window.UJSA_EarlyMessageListener) {
        window.UJSA_EarlyMessageListener = function(event) {
          var data = event.data || {};
          
          // Ignorer les messages de l'iframe elle-même
          if (event.origin === window.location.origin) {
            return;
          }
          
          // Debug: logger tous les messages postMessage reçus
          if (data.type === 'SET_TOKEN' || data.type === 'SET_SLUG' || data.type === 'UNITY_READY') {
            console.log('[UJSA] 📩 Message reçu (early) - type:', data.type, 'origin:', event.origin);
          }
          
          if (!window.UJSA_IsOriginAllowed(event.origin)) {
            if (data.type === 'SET_TOKEN' || data.type === 'SET_SLUG') {
              console.warn('[UJSA] ⚠ Origin non autorisé:', event.origin, '- Autorisés:', window.UJSA_ALLOWED_ORIGINS);
            }
            return;
          }
          
          if (!window.UJSA_PARENT_ORIGIN) {
            window.UJSA_PARENT_ORIGIN = event.origin;
            console.log('[UJSA] ✓ Origin parent enregistré:', event.origin);
          }
          
          if (data.type === 'SET_TOKEN' && data.token) {
            console.log('[UJSA] ✓ Token reçu (early) - longueur:', data.token.length);
            window.UJSA_JWT = data.token;
          }
          if (data.type === 'SET_SLUG' && data.slug) {
            console.log('[UJSA] ✓ Slug reçu (early):', data.slug);
            window.UJSA_SLUG = data.slug;
          }
        };
        
        window.addEventListener('message', window.UJSA_EarlyMessageListener);
      }
    })();
  `,
  
  $UJSA_EarlyInit: function() {},
  
  UJSA_PARENT_ORIGIN: null,
  
  PostMessage_Init__deps: ['$UJSA_EarlyInit'],
  PostMessage_Init: function() {
    var inIframe = window.self !== window.top;
    
    if (!inIframe) {
      window.UJSA_InIframe = false;
      return 0;
    }
    
    window.UJSA_InIframe = true;
    console.log('[UJSA] PostMessage_Init appelé - Unity est prêt');
    
    // IMPORTANT: Stocker la référence à SendMessage pour pouvoir l'utiliser depuis les listeners
    // SendMessage est disponible ici car cette fonction est appelée depuis C# via DllImport
    window.UJSA_SendMessage = function(gameObject, method, param) {
      try {
        // Essayer d'abord via unityInstance (Unity 2020+)
        if (window.unityInstance && typeof window.unityInstance.SendMessage === 'function') {
          window.unityInstance.SendMessage(gameObject, method, param);
          return true;
        }
        // Essayer via gameInstance (Unity 2019)
        if (window.gameInstance && typeof window.gameInstance.SendMessage === 'function') {
          window.gameInstance.SendMessage(gameObject, method, param);
          return true;
        }
        // Essayer SendMessage global (ancien Unity)
        if (typeof SendMessage === 'function') {
          SendMessage(gameObject, method, param);
          return true;
        }
        console.error('[UJSA] ✗ Aucune méthode SendMessage trouvée');
        return false;
      } catch (e) {
        console.error('[UJSA] ✗ Erreur SendMessage:', e);
        return false;
      }
    };
    
    // Fonction pour envoyer des accusés de réception au parent
    window.UJSA_SendAck = function(type) {
      var parentOrigin = window.UJSA_PARENT_ORIGIN || '*';
      try {
        window.parent.postMessage({ type: type }, parentOrigin);
        console.log('[UJSA] ✓ ACK envoyé au parent:', type);
        return true;
      } catch (e) {
        console.error('[UJSA] ✗ Erreur envoi ACK:', e);
        return false;
      }
    };
    
    if (!window.UJSA_MessageListener) {
      if (window.UJSA_EarlyMessageListener) {
        window.removeEventListener('message', window.UJSA_EarlyMessageListener);
        window.UJSA_EarlyMessageListener = null;
      }
      
      window.UJSA_MessageListener = function(event) {
        var data = event.data || {};
        
        // Ignorer les messages de l'iframe elle-même
        if (event.origin === window.location.origin) {
          return;
        }
        
        // Debug: logger tous les messages postMessage reçus
        if (data.type === 'SET_TOKEN' || data.type === 'SET_SLUG') {
          console.log('[UJSA] 📩 Message reçu (late) - type:', data.type, 'origin:', event.origin);
        }
        
        var isAllowed = window.UJSA_IsOriginAllowed ? window.UJSA_IsOriginAllowed(event.origin) : false;
        
        if (!isAllowed) {
          if (data.type === 'SET_TOKEN' || data.type === 'SET_SLUG') {
            console.warn('[UJSA] ⚠ Origin non autorisé:', event.origin, '- Autorisés:', window.UJSA_ALLOWED_ORIGINS);
          }
          return;
        }
        
        if (!window.UJSA_PARENT_ORIGIN) {
          window.UJSA_PARENT_ORIGIN = event.origin;
          console.log('[UJSA] ✓ Origin parent enregistré:', event.origin);
        }
        
        if (data.type === 'SET_TOKEN' && data.token) {
          console.log('[UJSA] ✓ Token reçu via postMessage');
          window.UJSA_JWT = data.token;
          
          // Utiliser notre wrapper SendMessage stocké
          if (window.UJSA_SendMessage) {
            var success = window.UJSA_SendMessage('PostMessageBridge', 'OnTokenReceivedFromJS', data.token);
            if (success) {
              console.log('[UJSA] ✓ Token envoyé à Unity via SendMessage');
              // Envoyer l'accusé de réception au parent
              window.UJSA_SendAck('TOKEN_RECEIVED');
            }
          } else {
            console.warn('[UJSA] ⚠ SendMessage non disponible, token stocké pour récupération ultérieure');
          }
        }
        
        // Gestion du slug projet
        if (data.type === 'SET_SLUG' && data.slug) {
          console.log('[UJSA] ✓ Slug reçu via postMessage:', data.slug);
          window.UJSA_SLUG = data.slug;
          
          if (window.UJSA_SendMessage) {
            var success = window.UJSA_SendMessage('PostMessageBridge', 'OnSlugReceivedFromJS', data.slug);
            if (success) {
              console.log('[UJSA] ✓ Slug envoyé à Unity via SendMessage');
              // Envoyer l'accusé de réception au parent
              window.UJSA_SendAck('SLUG_RECEIVED');
            }
          } else {
            console.warn('[UJSA] ⚠ SendMessage non disponible, slug stocké pour récupération ultérieure');
          }
        }
      };
      
      window.addEventListener('message', window.UJSA_MessageListener);
    }
    
    // Vérifier si un token a été reçu AVANT que Unity soit prêt
    if (window.UJSA_JWT && window.UJSA_JWT.length > 0) {
      console.log('[UJSA] ✓ Token déjà présent (reçu avant init Unity), envoi à Unity...');
      if (window.UJSA_SendMessage) {
        var success = window.UJSA_SendMessage('PostMessageBridge', 'OnTokenReceivedFromJS', window.UJSA_JWT);
        if (success) {
          console.log('[UJSA] ✓ Token pré-existant envoyé à Unity');
        }
      }
    } else {
      console.log('[UJSA] Aucun token pré-existant, attente de SET_TOKEN...');
    }
    
    return 1;
  },
  
  PostMessage_IsInIframe: function() {
    return window.UJSA_InIframe ? 1 : 0;
  },
  
  PostMessage_GetToken: function(bufferPtr, bufferSize) {
    if (!window.UJSA_JWT) {
      return 0;
    }
    
    stringToUTF8(window.UJSA_JWT, bufferPtr, bufferSize);
    return 1;
  },
  
  PostMessage_HasToken: function() {
    return (window.UJSA_JWT && window.UJSA_JWT.length > 0) ? 1 : 0;
  },
  
  PostMessage_NotifyLogin: function(tokenPtr) {
    if (!window.UJSA_InIframe) {
      return 0;
    }
    
    var token = UTF8ToString(tokenPtr || 0) || '';
    if (!token) {
      return 0;
    }
    
    var parentOrigin = window.UJSA_PARENT_ORIGIN || '*';
    
    try {
      window.parent.postMessage({ type: 'UJSA_LOGIN', token: token }, parentOrigin);
      return 1;
    } catch (e) {
      console.error('[UJSA] Erreur postMessage:', e);
      return 0;
    }
  },

  // Notifie le parent qu'un logout a été déclenché côté Unity.
  // Permet au parent de purger son token et d'éviter de le renvoyer immédiatement.
  PostMessage_NotifyLogout: function() {
    if (!window.UJSA_InIframe) {
      return 0;
    }

    var parentOrigin = window.UJSA_PARENT_ORIGIN || '*';
    try {
      window.parent.postMessage({ type: 'UJSA_LOGOUT' }, parentOrigin);
      return 1;
    } catch (e) {
      console.error('[UJSA] Erreur postMessage logout:', e);
      return 0;
    }
  },
  
  PostMessage_ClearToken: function() {
    window.UJSA_JWT = null;
  },
  
  // Envoie un signal au parent pour dire que Unity est prêt à recevoir le token
  PostMessage_NotifyReady: function() {
    if (!window.UJSA_InIframe) {
      console.log('[UJSA] Pas dans iframe, NotifyReady ignoré');
      return 0;
    }
    
    // Toujours utiliser '*' pour UNITY_READY car on ne connaît pas encore l'origin du parent
    try {
      window.parent.postMessage({ type: 'UNITY_READY' }, '*');
      console.log('[UJSA] ✓ Signal UNITY_READY envoyé au parent (origin: *)');
      return 1;
    } catch (e) {
      console.error('[UJSA] ✗ Erreur envoi UNITY_READY:', e);
      return 0;
    }
  },
  
  PostMessage_SetToken: function(tokenPtr) {
    var token = UTF8ToString(tokenPtr || 0) || '';
    if (token) {
      window.UJSA_JWT = token;
      return 1;
    }
    return 0;
  },
  
  PostMessage_SetParentOrigin: function(originPtr) {
    var origin = UTF8ToString(originPtr || 0) || '';
    if (origin) {
      window.UJSA_PARENT_ORIGIN = origin;
      if (window.UJSA_ALLOWED_ORIGINS && window.UJSA_ALLOWED_ORIGINS.indexOf(origin) === -1) {
        window.UJSA_ALLOWED_ORIGINS.push(origin);
      }
      return 1;
    }
    return 0;
  },
  
  PostMessage_AddAllowedOrigin: function(originPtr) {
    var origin = UTF8ToString(originPtr || 0) || '';
    if (origin) {
      if (!window.UJSA_ALLOWED_ORIGINS) {
        window.UJSA_ALLOWED_ORIGINS = [];
      }
      if (window.UJSA_ALLOWED_ORIGINS.indexOf(origin) === -1) {
        window.UJSA_ALLOWED_ORIGINS.push(origin);
        return 1;
      }
    }
    return 0;
  },
  
  PostMessage_GetParentOrigin: function(bufferPtr, bufferSize) {
    var origin = window.UJSA_PARENT_ORIGIN || '';
    if (origin) {
      stringToUTF8(origin, bufferPtr, bufferSize);
      return 1;
    }
    return 0;
  }
});
