package com.mobify.astro.plugins;

import android.graphics.Color;
import android.support.annotation.NonNull;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.SearchView;
import android.widget.EditText;

import com.mobify.astro.AstroActivity;
import com.mobify.astro.AstroPlugin;
import com.mobify.astro.PluginResolver;
import com.mobify.astro.R;
import com.mobify.astro.messaging.EventRegistrar;
import com.mobify.astro.messaging.MessageSender;
import com.mobify.astro.messaging.annotations.RpcMethod;
import com.mobify.astro.utilities.LocaleChangedListener;
import com.mobify.astro.utilities.LocalizationUtilities;

import org.json.JSONException;
import org.json.JSONObject;


public class SearchBarPlugin extends AstroPlugin implements LocaleChangedListener {

    static final String TAG = SearchBarPlugin.class.getName();

    private SearchView searchView;
    private LocalizationUtilities localizationUtilities;
    private String placeholderTextKey = "search_bar_hint";
    private Boolean userIsEditing;

    public SearchBarPlugin(@NonNull AstroActivity activity, @NonNull PluginResolver pluginResolver,
                           @NonNull EventRegistrar eventRegistrar, @NonNull MessageSender messageSender) {
        super(activity, pluginResolver, eventRegistrar, messageSender);

        localizationUtilities = activity.getLocalizationUtilities();
        localizationUtilities.addLocaleChangedListener(this);

        searchView = new SearchView(activity);
        searchView.setIconifiedByDefault(false);

        setLocalizedPlaceholderText();

        userIsEditing = false;

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                JSONObject params = createSearchTermsParams(query);
                triggerEvent("search:submitted", params);
                searchView.setQuery("", false);
                userIsEditing = false;
                searchView.clearFocus();
                return true;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                JSONObject params = createSearchTermsParams(newText);
                triggerEvent("search:changed", params);
                return true;
            }
        });

        searchView.setOnQueryTextFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus && !v.hasFocus() && userIsEditing) {
                    /**
                     *  Note: hasFocus and v.hasFocus() are not the same!
                     *
                     *  We do not want `search:cancelled` triggered when:
                     *  - blur() is called
                     *  - hideTopView(searchBarPlugin) is called on the parent
                     *
                     *  v.hasFocus() will be `true` in these cases.
                    */
                    triggerEvent("search:cancelled", null);
                    userIsEditing = false;
                }
                if (hasFocus) {
                    userIsEditing = true;
                }
            }
        });
    }

    private void setLocalizedPlaceholderText() {
        searchView.setQueryHint(localizationUtilities.translate(placeholderTextKey));
    }

    private JSONObject createSearchTermsParams(String query) {
        JSONObject params = new JSONObject();
        try {
            params.put("searchTerms", query);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return params;
    }

    @Override
    public View getView() {
        return searchView;
    }

    @RpcMethod(methodName = "blur")
    public void blur() {
        userIsEditing = false;
        searchView.clearFocus();
    }

    @RpcMethod(methodName = "focus")
    public void focus() {
        int editTextId = searchView.getContext().getResources().getIdentifier("android:id/search_src_text", null, null);
        EditText editText = (EditText) searchView.findViewById(editTextId);
        editText.requestFocus();
        InputMethodManager inputManager = (InputMethodManager) activity.getSystemService(activity.INPUT_METHOD_SERVICE);
        inputManager.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
    }

    @RpcMethod(methodName = "setQuery", parameterNames = {"query"})
    public void setQuery(String query) {
        searchView.setQuery(query, false);
    }

    @RpcMethod(methodName = "setPlaceholderText", parameterNames = {"text"})
    public void setPlaceholderText(String text) {
        placeholderTextKey = text;
        setLocalizedPlaceholderText();
    }

    @RpcMethod(methodName = "setBackgroundColor", parameterNames = {"color"})
    public void setBackgroundColor(String color) {
        searchView.setBackgroundColor(Color.parseColor(color));
    }

    @RpcMethod(methodName = "submit")
    public void submit() {
        searchView.setQuery(searchView.getQuery(), true);
    }

    @Override
    public void localeDidChange() {
        setLocalizedPlaceholderText();
        int direction =  localizationUtilities.leftToRight() ? View.LAYOUT_DIRECTION_LTR : View.LAYOUT_DIRECTION_RTL;
        int linearLayoutId = activity.getResources().getIdentifier("android:id/search_edit_frame", null, null);
        searchView.findViewById(linearLayoutId).setLayoutDirection(direction);
    }
}
