(() => {
  if (window.mazexchain?.isMazeXChain) return;

  const REQUEST_TYPE = 'MAZEXCHAIN_PROVIDER_REQUEST';
  const RESPONSE_TYPE = 'MAZEXCHAIN_PROVIDER_RESPONSE';
  let nextId = 1;
  const pending = new Map();

  window.addEventListener('message', (event) => {
    if (event.source !== window) return;
    const message = event.data;
    if (!message || message.type !== RESPONSE_TYPE || !pending.has(message.id)) return;
    const { resolve, reject } = pending.get(message.id);
    pending.delete(message.id);
    if (message.ok) {
      resolve(message.result);
      return;
    }
    const error = new Error(message.error?.message || 'MazeXChain Wallet request failed.');
    error.code = message.error?.code || 'MAZEXCHAIN_WALLET_ERROR';
    reject(error);
  });

  window.mazexchain = {
    isMazeXChain: true,
    version: '0.1.0',
    request({ method, params = {} } = {}) {
      if (!method) return Promise.reject(new Error('MazeXChain Wallet request method is required.'));
      const id = `mazex-${Date.now()}-${nextId}`;
      nextId += 1;
      return new Promise((resolve, reject) => {
        pending.set(id, { resolve, reject });
        window.postMessage(
          {
            type: REQUEST_TYPE,
            id,
            method,
            params,
          },
          window.location.origin,
        );
      });
    },
  };

  window.dispatchEvent(new Event('mazexchain#initialized'));
})();
