// React Native polyfills for crypto and Web3 functionality
// Consolidated "batteries included" approach for React Native SDK

import { Buffer } from 'buffer';
import { setupWeb3InstanceofPolyfill } from './web3-polyfills';

// Initialize React Native polyfills
export const initializeReactNativePolyfills = (): boolean => {
  try {
    // Set up basic global environment
    (global as any).global = global;
    (global as any).Buffer = Buffer;

    // Add process if missing
    if (typeof global !== 'undefined' && !global.process) {
      global.process = { 
        env: {},
        version: '16.0.0',
        nextTick: (callback: () => void) => setTimeout(callback, 0)
      } as any;
    }

    // Initialize crypto polyfills (CRITICAL for Web3)
    require('react-native-get-random-values');
    
    // Crypto polyfill for better Web3 compatibility
    if (typeof global !== 'undefined' && !(global as any).crypto) {
      (global as any).crypto = {
        getRandomValues: (arr: any) => {
          require('react-native-get-random-values');
          return (global as any).crypto.getRandomValues(arr);
        },
        randomUUID: () => {
          const hex = '0123456789abcdef';
          let result = '';
          for (let i = 0; i < 32; i++) {
            result += hex[Math.floor(Math.random() * 16)];
            if (i === 7 || i === 11 || i === 15 || i === 19) result += '-';
          }
          return result;
        }
      };
    }
    
    // Add URL polyfill for Web3 compatibility
    if (typeof global !== 'undefined' && !(global as any).URL) {
      try {
        // Try to use react-native-url-polyfill if available
        require('react-native-url-polyfill/auto');
      } catch {
        // Fallback to basic URL implementation
        (global as any).URL = class URL {
          constructor(public href: string) {}
          toString() { return this.href; }
        } as any;
      }
    }

    // Add btoa/atob polyfills for Web3 compatibility
    if (typeof global !== 'undefined') {
      if (!(global as any).btoa) {
        (global as any).btoa = (str: string) => Buffer.from(str, 'binary').toString('base64');
      }
      if (!(global as any).atob) {
        (global as any).atob = (str: string) => Buffer.from(str, 'base64').toString('binary');
      }
    }

    // EventTarget polyfill for Web3 providers
    if (typeof global !== 'undefined' && !(global as any).EventTarget) {
      (global as any).EventTarget = class EventTarget {
        private listeners: { [key: string]: ((...args: any[]) => void)[] } = {};
        
        addEventListener(type: string, listener: (...args: any[]) => void) {
          if (!this.listeners[type]) {
            this.listeners[type] = [];
          }
          this.listeners[type].push(listener);
        }
        
        removeEventListener(type: string, listener: (...args: any[]) => void) {
          if (this.listeners[type]) {
            const index = this.listeners[type].indexOf(listener);
            if (index > -1) {
              this.listeners[type].splice(index, 1);
            }
          }
        }
        
        dispatchEvent(event: any) {
          if (this.listeners[event.type]) {
            this.listeners[event.type].forEach(listener => {
              listener(event);
            });
          }
          return true;
        }
      };
    }

    // Performance polyfill
    if (typeof global !== 'undefined' && !(global as any).performance) {
      (global as any).performance = {
        now: () => Date.now(),
        timeOrigin: Date.now()
      };
    }

    // Stream polyfill (minimal)
    if (typeof global !== 'undefined' && !(global as any).stream) {
      (global as any).stream = {
        Readable: class {},
        Writable: class {},
        Transform: class {}
      };
    }

    // Web3 specific polyfills for instanceof issues
    setupWeb3Polyfills();
    setupWeb3InstanceofPolyfill();
    
    return true;
  } catch (error) {
    console.warn('[PERS SDK] Failed to initialize some polyfills:', error);
    return true;
  }
};

// Web3 specific polyfills to fix instanceof issues
const setupWeb3Polyfills = () => {
  try {
    // Ensure Symbol polyfill for constructor comparison
    if (typeof global !== 'undefined' && !(global as any).Symbol) {
      (global as any).Symbol = {
        for: (key: string) => `Symbol(${key})`,
        iterator: '@@iterator',
        toStringTag: '@@toStringTag'
      };
    }

    // Add constructor.name polyfill for better class detection
    if (typeof global !== 'undefined' && typeof Function !== 'undefined') {
      const originalToString = Function.prototype.toString;
      if (!Function.prototype.name) {
        Object.defineProperty(Function.prototype, 'name', {
          get: function() {
            const match = originalToString.call(this).match(/function\s*([^(]*)/);
            return match ? match[1] : '';
          }
        });
      }
    }

    // Module resolution enhancement for Web3
    if (typeof global !== 'undefined') {
      // Store reference to help with instanceof checks
      (global as any).__PERS_SDK_WEB3_POLYFILLS__ = true;
    }

  } catch (error) {
    console.warn('[PERS SDK] Web3 polyfills setup failed:', error);
  }
};

// Auto-initialize polyfills when SDK is imported
initializeReactNativePolyfills();

// Export utilities for advanced usage
export { createSafeWeb3Check } from './web3-polyfills';