package com.mappls.sdk.search.react;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;

import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.google.gson.Gson;
import com.mappls.sdk.geojson.Point;
import com.mappls.sdk.plugins.places.autocomplete.PlaceAutocomplete;
import com.mappls.sdk.plugins.places.autocomplete.model.MapplsFavoritePlace;
import com.mappls.sdk.plugins.places.autocomplete.model.PlaceOptions;
import com.mappls.sdk.services.api.autosuggest.AutoSuggestCriteria;

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

public class MapplsReactNativePlacePickerModule extends ReactContextBaseJavaModule {

    private final ReactApplicationContext reactContext;
    private Promise promise;
    private ActivityEventListener mActivityEventListener = new ActivityEventListener() {
        @Override
        public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
            if (requestCode == 102) {
                if (resultCode == Activity.RESULT_OK) {
                    if (promise != null) {
                        AutocompleteResult result = new AutocompleteResult();
                        result.setELocation(PlaceAutocomplete.getPlace(data));
                        result.setSuggestedSearch(PlaceAutocomplete.getSuggestedSearch(data));
                        result.setRequestForCurrentLocation(PlaceAutocomplete.isRequestForCurrentLocation(data));
                        result.setMapplsFavoritePlace(PlaceAutocomplete.getFavoritePlace(data));
                        promise.resolve(new Gson().toJson(result));
                    }
                } else {
                    promise.reject("Cancel", "Close");

                }
            }

        }

        @Override
        public void onNewIntent(Intent intent) {

        }


    };

    public MapplsReactNativePlacePickerModule(ReactApplicationContext reactContext) {
        super(reactContext);
        this.reactContext = reactContext;
    }

    @Override
    public void initialize() {
        super.initialize();
        reactContext.addActivityEventListener(mActivityEventListener);
    }

    @Override
    public boolean canOverrideExistingModule() {
        return true;
    }

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

        //Pods
        constants.put("POD_SUB_LOCALITY_KEY", AutoSuggestCriteria.POD_SUB_LOCALITY);
        constants.put("POD_LOCALITY_KEY", AutoSuggestCriteria.POD_LOCALITY);
        constants.put("POD_CITY_KEY", AutoSuggestCriteria.POD_CITY);
        constants.put("POD_VILLAGE_KEY", AutoSuggestCriteria.POD_VILLAGE);
        constants.put("POD_SUB_DISTRICT_KEY", AutoSuggestCriteria.POD_SUB_DISTRICT);
        constants.put("POD_DISTRICT_KEY", AutoSuggestCriteria.POD_DISTRICT);
        constants.put("POD_STATE_KEY", AutoSuggestCriteria.POD_STATE);
        constants.put("POD_SUB_SUB_LOCALITY_KEY", AutoSuggestCriteria.POD_SUB_SUB_LOCALITY);

        //attributionHorizontalAlignment
        constants.put("GRAVITY_LEFT_KEY", PlaceOptions.GRAVITY_LEFT);
        constants.put("GRAVITY_CENTER_KEY", PlaceOptions.GRAVITY_CENTER);
        constants.put("GRAVITY_RIGHT_KEY", PlaceOptions.GRAVITY_RIGHT);

        //attributionVerticalAlignment
        constants.put("GRAVITY_TOP_KEY", PlaceOptions.GRAVITY_TOP);
        constants.put("GRAVITY_BOTTOM_KEY", PlaceOptions.GRAVITY_BOTTOM);


        //logoSize
        constants.put("SIZE_SMALL_KEY", PlaceOptions.SIZE_SMALL);
        constants.put("SIZE_MEDIUM_KEY", PlaceOptions.SIZE_MEDIUM);
        constants.put("SIZE_LARGE_KEY", PlaceOptions.SIZE_LARGE);
        return constants;
    }

    @Override
    public String getName() {
        return "MapplsReactNativePlacePicker";
    }

    @ReactMethod
    public void openPlaceWidget(final ReadableMap map, Promise promise) {

        this.promise = promise;
        if (getCurrentActivity() == null) {
            promise.reject("Error", "You are not directly attached with activity");
            return;
        }

        PlaceOptions.Builder placeOptionsBuilder = PlaceOptions.builder();
        if(map.hasKey("autoSuggestBaseUrl")) {
            String baseUrl = map.getString("autoSuggestBaseUrl");
            placeOptionsBuilder.autoSuggestBaseUrl(baseUrl);
        }
        if (map.hasKey("location")) {
            ReadableArray location = map.getArray("location");
            //val latLong: List<String> = searchMap.getString("location")!!.split(",")
            if (location != null && location.size() == 2) {
                double latitude = location.getDouble(1);//latLong[1].toDouble()
                double longitude = location.getDouble(0);//latLong[0].toDouble()
                placeOptionsBuilder.location(Point.fromLngLat(longitude, latitude));
            }
        }
        if (map.hasKey("historyCount")) {
            int historyCount = map.getInt("historyCount");
            placeOptionsBuilder.historyCount(historyCount);
        }
        if (map.hasKey("zoom")) {
            double zoom = map.getDouble("zoom");
            placeOptionsBuilder.zoom(zoom);
        }
        if (map.hasKey("saveHistory")) {
            boolean saveHistory = map.getBoolean("saveHistory");
            placeOptionsBuilder.saveHistory(saveHistory);
        }
        if (map.hasKey("pod")) {
            String pod = map.getString("pod");
            placeOptionsBuilder.pod(pod);
        }
        if (map.hasKey("backgroundColor")) {
            int backgroundColor = Color.parseColor(map.getString("backgroundColor"));
            placeOptionsBuilder.backgroundColor(backgroundColor);
        }
        if (map.hasKey("tokenizeAddress")) {
            boolean tokenizeAddress = map.getBoolean("tokenizeAddress");
            if (tokenizeAddress)
                placeOptionsBuilder.tokenizeAddress(true);
        }
        if (map.hasKey("toolbarColor")) {
            int toolbarColor = Color.parseColor(map.getString("toolbarColor"));
            placeOptionsBuilder.toolbarColor(toolbarColor);
        }
        if (map.hasKey("hint")) {
            String hint = map.getString("hint");
            placeOptionsBuilder.hint(hint);
        }
        if (map.hasKey("filter")) {
            String filter = map.getString("filter");
            placeOptionsBuilder.filter(filter);
        }
        if (map.hasKey("favoritePlaces")) {
            ReadableArray readableArray = map.getArray("favoritePlaces");
            if(readableArray != null) {
                List<MapplsFavoritePlace> mapplsFavoritePlaces = new ArrayList<>();
                for (int i = 0; i < readableArray.size(); i++) {
                    String favorite = readableArray.getString(i);
                    mapplsFavoritePlaces.add(new Gson().fromJson(favorite, MapplsFavoritePlace.class));
                }
                placeOptionsBuilder.favoritePlaces(mapplsFavoritePlaces);
            }
        }
        if (map.hasKey("favoriteCount")) {
            int count = map.getInt("favoriteCount");
            placeOptionsBuilder.favoriteCount(count);
        }

        if (map.hasKey("attributionVerticalAlignment")) {
            int attributionVerticalAlignment = map.getInt("attributionVerticalAlignment");
            placeOptionsBuilder.attributionHorizontalAlignment(attributionVerticalAlignment);
        }
        if (map.hasKey("attributionHorizontalAlignment")) {
            int attributionHorizontalAlignment = map.getInt("attributionHorizontalAlignment");
            placeOptionsBuilder.attributionVerticalAlignment(attributionHorizontalAlignment);
        }
        if (map.hasKey("logoSize")) {
            int logoSize = map.getInt("logoSize");
            placeOptionsBuilder.logoSize(logoSize);
        }

        if (map.hasKey("userAddedLocationEnable") && !map.isNull("userAddedLocationEnable")) {
            boolean userAddedLocationEnable = map.getBoolean("userAddedLocationEnable");
            placeOptionsBuilder.userAddedLocationEnable(userAddedLocationEnable);
        }

        if (map.hasKey("limit") && !map.isNull("limit")) {
            int limit = map.getInt("limit");
            placeOptionsBuilder.limit(limit);
        }
        if (map.hasKey("enableTextSearch") && !map.isNull("enableTextSearch")) {
            boolean enableTextSearch = map.getBoolean("enableTextSearch");
            placeOptionsBuilder.enableTextSearch(enableTextSearch);
        }

        if (map.hasKey("minCharactersForSearch") && !map.isNull("minCharactersForSearch")) {
            int minCharactersForSearch = map.getInt("minCharactersForSearch");
            placeOptionsBuilder.minCharactersForSearch(minCharactersForSearch);
        }
        if (map.hasKey("statusBarColor") && !map.isNull("statusBarColor")) {
            int statusBarColor = Color.parseColor(map.getString("statusBarColor"));
            placeOptionsBuilder.statusBarColor(statusBarColor);
        }
        if (map.hasKey("toolbarTintColor") && !map.isNull("toolbarTintColor")) {
            int toolbarTintColor = Color.parseColor(map.getString("toolbarTintColor"));
            placeOptionsBuilder.toolbarTintColor(toolbarTintColor);
        }
        if (map.hasKey("showPoweredByText") && !map.isNull("showPoweredByText")) {
            boolean showPoweredByText = map.getBoolean("showPoweredByText");
            placeOptionsBuilder.showPoweredByText(showPoweredByText);
        }
        if (map.hasKey("hyperLocal") && !map.isNull("hyperLocal")) {
            boolean hyperLocal = map.getBoolean("hyperLocal");
            placeOptionsBuilder.hyperLocal(hyperLocal);
        }
        if (map.hasKey("bridge") && !map.isNull("bridge")) {
            boolean bridge = map.getBoolean("bridge");
            placeOptionsBuilder.bridge(bridge);
        }
        if (map.hasKey("isShowCurrentLocation") && !map.isNull("isShowCurrentLocation")) {
            boolean isShowCurrentLocation = map.getBoolean("isShowCurrentLocation");
            placeOptionsBuilder.isShowCurrentLocation(isShowCurrentLocation);
        }
        if (map.hasKey("currentLocationTextColor") && !map.isNull("currentLocationTextColor")) {
            int currentLocationTextColor = Color.parseColor(map.getString("currentLocationTextColor"));
            placeOptionsBuilder.currentLocationTextColor(currentLocationTextColor);
        }
        if(map.hasKey("debounce") && ! map.isNull("debounce")) {
            Integer debounce = map.getInt("debounce");
            placeOptionsBuilder.debounce(debounce);
        }

        if (map.hasKey("resultBackgroundColor")) {
            int resultBackgroundColor = Color.parseColor(map.getString("resultBackgroundColor"));
            placeOptionsBuilder.resultBackgroundColor(resultBackgroundColor);
        }
        if (map.hasKey("placeNameTextColor")) {
            int placeNameTextColor = Color.parseColor(map.getString("placeNameTextColor"));
            placeOptionsBuilder.placeNameTextColor(placeNameTextColor);
        }
        if (map.hasKey("addressTextColor")) {
            int addressTextColor = Color.parseColor(map.getString("addressTextColor"));
            placeOptionsBuilder.addressTextColor(addressTextColor);
        }
        if (map.hasKey("savedPlaceNameTextColor")) {
            int savedPlaceNameTextColor = Color.parseColor(map.getString("savedPlaceNameTextColor"));
            placeOptionsBuilder.savedPlaceNameTextColor(savedPlaceNameTextColor);
        }
        if (map.hasKey("favoritePlaceNameTextColor")) {
            int favoritePlaceNameTextColor = Color.parseColor(map.getString("favoritePlaceNameTextColor"));
            placeOptionsBuilder.favoritePlaceNameTextColor(favoritePlaceNameTextColor);
        }
        if (map.hasKey("distanceTextColor")) {
            int distanceTextColor = Color.parseColor(map.getString("distanceTextColor"));
            placeOptionsBuilder.distanceTextColor(distanceTextColor);
        }
        if (map.hasKey("errorBackgroundColor")) {
            int errorBackgroundColor = Color.parseColor(map.getString("errorBackgroundColor"));
            placeOptionsBuilder.errorBackgroundColor(errorBackgroundColor);
        }
        if (map.hasKey("errorTextColor")) {
            int errorTextColor = Color.parseColor(map.getString("errorTextColor"));
            placeOptionsBuilder.errorTextColor(errorTextColor);
        }
        if (map.hasKey("hintColor")) {
            int hintColor = Color.parseColor(map.getString("hintColor"));
            placeOptionsBuilder.hintColor(hintColor);
        }
        if (map.hasKey("poweredByTextColor")) {
            int poweredByTextColor = Color.parseColor(map.getString("poweredByTextColor"));
            placeOptionsBuilder.poweredByTextColor(poweredByTextColor);
        }
        if (map.hasKey("attributionBackgroundColor")) {
            int attributionBackgroundColor = Color.parseColor(map.getString("attributionBackgroundColor"));
            placeOptionsBuilder.attributionBackgroundColor(attributionBackgroundColor);
        }
        if (map.hasKey("currentLocationBackground")) {
            int currentLocationBackground = Color.parseColor(map.getString("currentLocationBackground"));
            placeOptionsBuilder.currentLocationBackground(currentLocationBackground);
        }
        if (map.hasKey("responseLang")) {
            String responseLang = map.getString("responseLang");
            placeOptionsBuilder.responseLang(responseLang);
        }
        Intent intent = new PlaceAutocomplete.IntentBuilder()
                .placeOptions(placeOptionsBuilder.build())
                .build(getCurrentActivity());
        getCurrentActivity().startActivityForResult(intent, 102);
    }

}