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);

        // Set the background color.
        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");
            snackbar.setAction(actionDetails.getString("title"), onClickListener);
            snackbar.setActionTextColor(actionDetails.getInt("color"));
        }

        if (options.hasKey("color")) {
            snackbarText.setTextColor(options.getInt("color"));
        } else {
            snackbarText.setTextColor(Color.WHITE);
        }

        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;
    }

}
@@ -2968,45 +2968,8 @@
 );%0A%0A
-        // Set the background color.%0A
     
@@ -3667,119 +3667,166 @@
     
-snackbar.setAction(actionDetails.getString(%22title%22), onClickListener);%0A            snackbar.setActionTextColor(
+String actionTitle = actionDetails.hasKey(%22title%22) ? actionDetails.getString(%22title%22) : %22%22;%0A            int actionTextColor = actionDetails.hasKey(%22color%22) ? 
 acti
@@ -3842,33 +3842,46 @@
 .getInt(%22color%22)
-)
+ : Color.WHITE
 ;%0A        %7D%0A%0A   
@@ -3878,49 +3878,61 @@
     
-%7D%0A%0A
     
-    if (options.hasKey(%22color%22)) %7B
+snackbar.setAction(actionTitle, onClickListener);
 %0A   
@@ -3944,32 +3944,34 @@
     snackbar
-Text
 .set
+Action
 TextColor(op
@@ -3972,31 +3972,23 @@
 lor(
-op
+ac
 tion
-s.getInt(%22c
+TextC
 olor
-%22)
 );%0A 
@@ -3999,20 +3999,99 @@
    %7D
- else %7B%0A    
+%0A%0A        int textColor = options.hasKey(%22color%22) ? options.getInt(%22color%22) : Color.WHITE;%0A
     
@@ -4124,31 +4124,19 @@
 lor(
+text
 Color
-.WHITE);%0A        %7D
+);
 %0A%0A  
@@ -4762,8 +4762,9 @@
     %7D%0A%0A%7D
+%0A

Fix unsafe ReadableMap access for action button