package com.github.alinz.reactnativewebviewbridge;

import javax.annotation.Nullable;
import java.util.Map;

import android.webkit.WebView;

import com.facebook.react.views.webview.ReactWebViewManager;
import com.facebook.react.views.webview.WebViewConfig;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.common.MapBuilder;

public class WebViewBridgeManager extends ReactWebViewManager {
  private static final String REACT_CLASS = "RCTWebViewBridge";

  public static final int COMMAND_INJECT_BRIDGE_SCRIPT = 100;
  public static final int COMMAND_SEND_TO_BRIDGE = 101;

  private boolean initializedBridge;

  public WebViewBridgeManager() {
    super();
    initializedBridge = false;
  }

  public WebViewBridgeManager(WebViewConfig webViewConfig) {
    super(webViewConfig);
    initializedBridge = false;
  }

  @Override
  public String getName() {
    return REACT_CLASS;
  }

  @Override
  public @Nullable Map<String, Integer> getCommandsMap() {
    Map<String, Integer> commandsMap = super.getCommandsMap();

    commandsMap.put("injectBridgeScript", COMMAND_INJECT_BRIDGE_SCRIPT);
    commandsMap.put("sendToBridge", COMMAND_SEND_TO_BRIDGE);

    return commandsMap;
  }

  @Override
  public void receiveCommand(WebView root, int commandId, @Nullable ReadableArray args) {
    super.receiveCommand(root, commandId, args);

    switch (commandId) {
      case COMMAND_INJECT_BRIDGE_SCRIPT:
        injectBridgeScript(root);
        break;
      case COMMAND_SEND_TO_BRIDGE:
        sendToBridge(root, args.getString(0));
        break;
      default:
        //do nothing!!!!
    }
  }

  private void sendToBridge(WebView root, String message) {
    //root.loadUrl("javascript:(function() {\n" + script + ";\n})();");
    String script = "WebViewBridge.onMessage('" + message + "');";
    root.evaluateJavascript(script, null);
  }

  private void injectBridgeScript(WebView root) {
    //this code needs to be called once per context
    if (!initializedBridge) {
      root.addJavascriptInterface(new JavascriptBridge((ReactContext)root.getContext()), "WebViewBridgeAndroid");
      initializedBridge = true;
      root.reload();
    }

    //this code needs to be executed everytime a url changes.
    root.evaluateJavascript(""
    + "(function() {"
        + "if (window.WebViewBridge) return;"
        + "var customEvent = document.createEvent('Event');"
        + "var WebViewBridge = {"
            + "send: function(message) { WebViewBridgeAndroid.send(message); },"
            + "onMessage: function() {}"
        + "};"
        + "window.WebViewBridge = WebViewBridge;"
        + "customEvent.initEvent('WebViewBridge', true, true);"
        + "document.dispatchEvent(customEvent);"
    +"}());", null);
  }
}

@@ -56,390 +56,300 @@
 ort 
-javax.annotation.Nullable;%0Aimport java.util.Map;%0A%0Aimport android.webkit.WebView;%0A%0Aimport com.facebook.react.views.webview.ReactWebViewManager;%0Aimport com.facebook.react.views.webview.WebViewConfig;%0Aimport com.facebook.react.bridge.ReadableArray;%0Aimport com.facebook.react.bridge.ReactContext;%0Aimport com.facebook.react.bridge.Writable
+android.webkit.WebView;%0A%0Aimport com.facebook.react.bridge.ReactContext;%0Aimport com.facebook.react.bridge.ReadableArray;%0Aimport com.facebook.react.views.webview.ReactWebViewManager;%0Aimport com.facebook.react.views.webview.WebViewConfig;%0A%0Aimport java.util.
 Map;%0A
+%0A
 import 
-com.facebook.react.common.MapBuilder
+javax.annotation.Nullable
 ;%0A%0Ap
@@ -1821,28 +1821,44 @@
  %22');%22;%0A    
-root
+WebViewBridgeManager
 .evaluateJav
@@ -1869,20 +1869,20 @@
 ipt(
+root, 
 script
-, null
 );%0A 
@@ -2086,16 +2086,17 @@
 Context)
+ 
 root.get
@@ -2194,24 +2194,25 @@
    %7D%0A%0A    //
+ 
 this code ne
@@ -2259,20 +2259,36 @@
 es.%0A    
-root
+WebViewBridgeManager
 .evaluat
@@ -2303,11 +2303,25 @@
 ipt(
+root, 
 %22%22%0A
+        
     
@@ -2334,24 +2334,28 @@
 nction() %7B%22%0A
+    
         + %22i
@@ -2392,24 +2392,28 @@
 n;%22%0A        
+   
+ 
 + %22var custo
@@ -2457,24 +2457,28 @@
 );%22%0A        
+    
 + %22var WebVi
@@ -2503,16 +2503,18 @@
         
+ 
+ 
 + %22send:
@@ -2586,16 +2586,18 @@
         
+  
 + %22onMes
@@ -2629,15 +2629,23 @@
     
+  
+  
 + %22%7D;%22%0A
+    
     
@@ -2698,16 +2698,20 @@
         
+    
 + %22custo
@@ -2766,16 +2766,20 @@
         
+ 
+   
 + %22docum
@@ -2819,24 +2819,309 @@
     
-+%22%7D());%22, null);
+        + %22%7D());%22);%0A  %7D%0A%0A  static private void evaluateJavascript(WebView root, String javascript) %7B%0A    if (android.os.Build.VERSION.SDK_INT %3E= android.os.Build.VERSION_CODES.KITKAT) %7B%0A      root.evaluateJavascript(javascript, null);%0A    %7D else %7B%0A      root.loadUrl(%22javascript:%22 + javascript);%0A    %7D
 %0A  %7D

Add support for Android 1+