package com.azendoo.reactnativesnackbar;

import android.graphics.Color;
import android.os.Build;
import com.google.android.material.snackbar.Snackbar;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SnackbarModule extends ReactContextBaseJavaModule{

    private static final String REACT_NAME = "RNSnackbar";

    private List<Snackbar> mActiveSnackbars = new ArrayList<>();

    public SnackbarModule(ReactApplicationContext reactContext) {
        super(reactContext);
    }

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

    @Override
    public Map<String, Object> getConstants() {
        final Map<String, Object> constants = new HashMap<>();

        constants.put("LENGTH_LONG", Snackbar.LENGTH_LONG);
        constants.put("LENGTH_SHORT", Snackbar.LENGTH_SHORT);
        constants.put("LENGTH_INDEFINITE", Snackbar.LENGTH_INDEFINITE);

        return constants;
    }

    @ReactMethod
    public void show(ReadableMap options, final Callback callback) {
        ViewGroup view;

        try {
            view = (ViewGroup) getCurrentActivity().getWindow().getDecorView().findViewById(android.R.id.content);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }

        if (view == null) return;

        mActiveSnackbars.clear();

        if (!view.hasWindowFocus()) {
            // The view is not focused, we should get all the modal views in the screen.
            ArrayList<View> modals = recursiveLoopChildren(view, new ArrayList<View>());

            for (View modal : modals) {
                if (modal == null) continue;

                displaySnackbar(modal, options, callback);
            }

            return;
        }

        displaySnackbar(view, options, callback);
    }

    @ReactMethod
    public void dismiss() {
        for (Snackbar snackbar : mActiveSnackbars) {
            if (snackbar != null) {
                snackbar.dismiss();
            }
        }

        mActiveSnackbars.clear();
    }

    private void displaySnackbar(View view, ReadableMap options, final Callback callback) {
        String title = options.hasKey("title") ? options.getString("title") : "";
        int duration = options.hasKey("duration") ? options.getInt("duration") : Snackbar.LENGTH_SHORT;

        Snackbar snackbar = Snackbar.make(view, title, duration);
        View snackbarView = snackbar.getView();
        TextView snackbarText = snackbarView.findViewById(com.google.android.material.R.id.snackbar_text);

        mActiveSnackbars.add(snackbar);

        if (options.hasKey("backgroundColor")) {
            snackbarView.setBackgroundColor(options.getInt("backgroundColor"));
        }

        if (options.hasKey("action")) {
            View.OnClickListener onClickListener = new View.OnClickListener() {
                // Prevent double-taps which can lead to a crash.
                boolean callbackWasCalled = false;

                @Override
                public void onClick(View v) {
                    if (callbackWasCalled) return;
                    callbackWasCalled = true;

                    callback.invoke();
                }
            };

            ReadableMap actionDetails = options.getMap("action");
            String actionTitle = actionDetails.hasKey("title") ? actionDetails.getString("title") : "";
            int actionTextColor = actionDetails.hasKey("color") ? actionDetails.getInt("color") : Color.WHITE;
            snackbar.setAction(actionTitle, onClickListener);
            snackbar.setActionTextColor(actionTextColor);
        }

        int textColor = options.hasKey("color") ? options.getInt("color") : Color.WHITE;
        snackbarText.setTextColor(textColor);

        snackbar.show();
    }

    /**
     * Loop through all child modals and save references to them.
     */
    private ArrayList<View> recursiveLoopChildren(ViewGroup view, ArrayList<View> modals) {
        if (view.getClass().getSimpleName().equalsIgnoreCase("ReactModalHostView")) {
            modals.add(view.getChildAt(0));
        }

        for (int i = view.getChildCount() - 1; i >= 0; i--) {
            final View child = view.getChildAt(i);

            if (child instanceof ViewGroup) {
                recursiveLoopChildren((ViewGroup) child, modals);
            }
        }

        return modals;
    }

}

@@ -70,33 +70,8 @@
 or;%0A
-import android.os.Build;%0A
 impo
@@ -627,16 +627,17 @@
 vaModule
+ 
 %7B%0A%0A    p
@@ -2517,65 +2517,44 @@
 e = 
-o
+getO
 ption
-s.hasKey(%22title%22) ? options.getString(
+Value(options, 
 %22title%22
-) :
+,
  %22%22
+)
 ;%0A  
@@ -2578,52 +2578,32 @@
 n = 
-o
+getO
 ption
-s.hasKey(%22duration%22) ? options.getInt(
+Value(options, 
 %22dur
@@ -2608,19 +2608,17 @@
 uration%22
-) :
+,
  Snackba
@@ -2631,16 +2631,88 @@
 TH_SHORT
+);%0A        int textColor = getOptionValue(options, %22color%22, Color.WHITE)
 ;%0A%0A     
@@ -2926,16 +2926,62 @@
 r_text);
+%0A        snackbarText.setTextColor(textColor);
 %0A%0A      
@@ -3191,24 +3191,255 @@
 action%22)) %7B%0A
+            ReadableMap actionOptions = options.getMap(%22action%22);%0A            String actionTitle = getOptionValue(actionOptions, %22title%22, %22%22);%0A            int actionTextColor = getOptionValue(actionOptions, %22color%22, Color.WHITE);%0A%0A
             
@@ -3883,542 +3883,125 @@
     
-ReadableMap actionDetails = options.getMap(%22action%22);%0A            String actionTitle = actionDetails.hasKey(%22title%22) ? actionDetails.getString(%22title%22) : %22%22;%0A            int actionTextColor = actionDetails.hasKey(%22color%22) ? actionDetails.getInt(%22color%22) : Color.WHITE;%0A            snackbar.setAction(actionTitle, onClickListener);%0A            snackbar.setActionTextColor(actionTextColor);%0A        %7D%0A%0A        int textColor = options.hasKey(%22color%22) ? options.getInt(%22color%22) : Color.WHITE;%0A        snackbarText.setTextColor(textColor);
+snackbar.setAction(actionTitle, onClickListener);%0A            snackbar.setActionTextColor(actionTextColor);%0A        %7D
 %0A%0A  
@@ -4626,10 +4626,331 @@
 %0A    %7D%0A%0A
+    private String getOptionValue(ReadableMap options, String key, String fallback) %7B%0A        return options.hasKey(key) ? options.getString(key) : fallback;%0A    %7D%0A%0A    private int getOptionValue(ReadableMap options, String key, int fallback) %7B%0A        return options.hasKey(key) ? options.getInt(key) : fallback;%0A    %7D%0A%0A
 %7D%0A

Add safe getOptionValue helpers