package org.deke.risk.riskahead.fragment;

import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.SwitchPreference;
import androidx.appcompat.app.AlertDialog;
import android.util.Log;

import com.android.volley.Request;
import com.android.volley.toolbox.StringRequest;
import com.google.firebase.crashlytics.FirebaseCrashlytics;

import org.deke.risk.riskahead.R;
import org.deke.risk.riskahead.SettingsActivity;
import org.deke.risk.riskahead.helper.AppConfig;
import org.deke.risk.riskahead.helper.AppController;
import org.deke.risk.riskahead.helper.SessionManager;
import org.deke.risk.riskahead.helper.ValidatedEditTextPreference;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

/**
 *
 * (C) Copyright 2016 RiskAhead (http://www.riskahead.net)
 * Developer & Contributor: Dennis Thießen (dennis.thiessen@riskahead.net)
 * Date of Release: 10.02.2016
 *
 */
public class SettingsFragment extends PreferenceFragment {
    private final static String TAG = SettingsFragment.class.getSimpleName();

    private ValidatedEditTextPreference prefUsername;
    private EditTextPreference prefSurname;
    private EditTextPreference prefName;
    private ValidatedEditTextPreference prefEmail;

    private SwitchPreference prefNotifications;
    private ListPreference prefRadius;
    private ListPreference prefFrequency;
    private SwitchPreference prefGPSENabled;
    private Preference prefLocation;

    public SessionManager session;
    public HashMap<String, String> user;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        session = new SessionManager(getActivity().getApplicationContext());
        user = session.getUserDetails();

        addPreferencesFromResource(R.xml.settings);

        initAccountPrefs();

        initNotificationPrefs();

        updatePrefs();
    }

    private void initNotificationPrefs() {
        prefNotifications = (SwitchPreference) getPreferenceManager().findPreference("notifyEnable");
        prefRadius = (ListPreference) getPreferenceManager().findPreference("notifyRadius");
        prefFrequency = (ListPreference) getPreferenceManager().findPreference("notifyFrequency");
        prefGPSENabled = (SwitchPreference) getPreferenceManager().findPreference("notifyEnableGPS");
        prefLocation = getPreferenceManager().findPreference("notifyChooseLocation");

        prefNotifications.setOnPreferenceChangeListener((preference, newValue) -> {
            String newStringValue = newValue.toString();
            session.setNotificationEnabled(Boolean.valueOf(newStringValue));
            return true;
        });

        prefRadius.setOnPreferenceChangeListener((preference, newValue) -> {
            String newStringValue = newValue.toString();

            if(session.getSubsPremium() || Integer.valueOf(newStringValue) < 25){
                session.setNotificationRadius(Integer.valueOf(newStringValue));
                ((ListPreference) preference).setValue(newValue.toString());
                preference.setSummary(prefRadius.getEntry());
                return true;
            }else{
                ((SettingsActivity) getActivity()).showMessage(getString(R.string.txt_premium_only));
                return false;
            }

        });


        prefFrequency.setOnPreferenceChangeListener((preference, newValue) -> {
            String newStringValue = newValue.toString();
            session.setNotificationPollFreq(Integer.valueOf(newStringValue));
            ((ListPreference) preference).setValue(newValue.toString());
            preference.setSummary(prefFrequency.getEntry());
            return true;
        });

        prefGPSENabled.setOnPreferenceChangeListener((preference, newValue) -> {
            String newStringValue = newValue.toString();
            session.setGPSForNotificationsEnabled(Boolean.valueOf(newStringValue));
            updatePrefs();
            return true;
        });

        prefLocation.setOnPreferenceClickListener(preference -> {
            if (session.getManualLocation().longitude != 0.0 && session.getManualLocation().latitude != 0.0) {
                ((SettingsActivity) getActivity()).getNotifyLocationFromMapActivity(Double.toString(session.getManualLocation().latitude) + " : " + Double.toString(session.getManualLocation().longitude));
            } else if(session.getLocation().longitude != 0.0 && session.getLocation().latitude != 0.0){
                ((SettingsActivity) getActivity()).getNotifyLocationFromMapActivity(Double.toString(session.getLocation().latitude) + " : " + Double.toString(session.getLocation().longitude));
            } else {
                ((SettingsActivity) getActivity()).getNotifyLocationFromMapActivity();
            }

            return true;
        });

        if(!session.getSubsPremium()){
            prefGPSENabled.setEnabled(false);
            prefLocation.setEnabled(false);

            session.setGPSForNotificationsEnabled(true);

            prefGPSENabled.setTitle(prefGPSENabled.getTitle() + " " + getResources().getString(R.string.txt_premium_only));
            prefLocation.setTitle(prefLocation.getTitle() + " " + getResources().getString(R.string.txt_premium_only));
        }
    }

    private void initAccountPrefs() {
        prefUsername = (ValidatedEditTextPreference) getPreferenceManager().findPreference("usernamePref");
        prefSurname = (EditTextPreference) getPreferenceManager().findPreference("surnamePref");
        prefName = (EditTextPreference) getPreferenceManager().findPreference("namePref");
        prefEmail = (ValidatedEditTextPreference) getPreferenceManager().findPreference("emailPref");
        Preference btnRequestPW = getPreferenceManager().findPreference("resetPassword");

        Preference.OnPreferenceChangeListener changeListener = (preference, newValue) -> {
            requestUpdateUserSettings(preference,newValue.toString());
            return true;
        };

        prefUsername.setOnPreferenceChangeListener(changeListener);
        prefSurname.setOnPreferenceChangeListener(changeListener);
        prefName.setOnPreferenceChangeListener(changeListener);
        prefEmail.setOnPreferenceChangeListener(changeListener);

        if(btnRequestPW != null){
            btnRequestPW.setOnPreferenceClickListener(preference -> {
                new AlertDialog.Builder(getActivity())
                        .setTitle(getResources().getString(R.string.txt_settings_resetpwtitle))
                        .setMessage(getResources().getString(R.string.txt_settings_resetpwtext))
                        .setPositiveButton(android.R.string.yes, (dialog, which) -> requestPasswordReset())
                        .setNegativeButton(android.R.string.no, (dialog, which) -> {
                            // do nothing
                        })
                        .setIcon(android.R.drawable.ic_dialog_alert)
                        .show();

                return true;
            });

            if(!user.get(SessionManager.PROVIDER_TYPE).equals("local")){
                btnRequestPW.setEnabled(false);
            }else{
                btnRequestPW.setEnabled(true);
            }
        }
    }

    private void updatePrefs() {
        user = session.getUserDetails();

        prefUsername.setText(user.get(SessionManager.KEY_USERNAME));
        prefSurname.setText(user.get(SessionManager.KEY_SURNAME));
        prefName.setText(user.get(SessionManager.KEY_NAME));
        prefEmail.setText(user.get(SessionManager.KEY_EMAIL));

        prefUsername.setSummary(user.get(SessionManager.KEY_USERNAME));
        prefSurname.setSummary(user.get(SessionManager.KEY_SURNAME));
        prefName.setSummary(user.get(SessionManager.KEY_NAME));
        prefEmail.setSummary(user.get(SessionManager.KEY_EMAIL));

        prefNotifications.setChecked(session.getNotificationEnabled());
        prefFrequency.setValue(Integer.toString(session.getNotificationPollFreq()));
        prefFrequency.setSummary(prefFrequency.getEntry());
        prefRadius.setValue(Integer.toString(session.getNotificationRadius()));
        prefRadius.setSummary(prefRadius.getEntry());
        prefGPSENabled.setChecked(session.isGPSForNotificationsEnabled());
        prefLocation.setSummary(getResources().getString(R.string.txt_settings_gps_loca_sum)+":\n"+Double.toString(session.getManualLocation().latitude)+" : "+Double.toString(session.getManualLocation().longitude));

        if(session.getSubsPremium()){
            if(session.isGPSForNotificationsEnabled()){
                prefLocation.setEnabled(false);
            }else{
                prefLocation.setEnabled(true);
            }
        }
    }

    private void requestPasswordReset() {
        ((SettingsActivity)getActivity()).showDialog();

        String tag_string_req = "requestpwreset";
        StringRequest strReq = getStringRequestResetPW(user.get(SessionManager.KEY_EMAIL));
        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    private StringRequest getStringRequestResetPW(final String email) {
        ((SettingsActivity) getActivity()).showDialog();
        return new StringRequest(Request.Method.POST, AppConfig.REST_REQUESTPWRESET, response -> {
            Log.d(TAG, "Resend E-Mail Response: " + response);
            ((SettingsActivity) getActivity()).hideDialog();

            try {
                JSONObject jObj = new JSONObject(response);
                boolean error = jObj.getBoolean("error");

                if (!error) {
                    ((SettingsActivity) getActivity()).showMessage(getString(R.string.alert_passwordreset_confirmation));
                }else{
                    String errorMsg = jObj.getString("error_msg");
                    FirebaseCrashlytics.getInstance().log("Error request email reset (Server returned error): " + errorMsg);
                    ((SettingsActivity) getActivity()).showMessage(getResources().getString(R.string.txt_errormsg_resetpw));
                }
            } catch (JSONException e) {
                FirebaseCrashlytics.getInstance().log("JSONException caught");
                FirebaseCrashlytics.getInstance().recordException(e);
            }

        }, error -> {
            FirebaseCrashlytics.getInstance().log("Error request email reset: " + error.getMessage());
            ((SettingsActivity) getActivity()).showMessage(getString(R.string.errormsg_couldnotretrieve));
            ((SettingsActivity) getActivity()).hideDialog();
        }) {

            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<>();
                params.put("email", email);

                return params;
            }
        };
    }

    private void requestUpdateUserSettings(Preference pref, String newValue) {
        ((SettingsActivity) getActivity()).showDialog();
        String username = prefUsername.getText(),name = prefName.getText(),surname = prefSurname.getText(),email = prefEmail.getText();

        switch (pref.getKey()){
            case "usernamePref":
                username = newValue;
                break;
            case "namePref":
                name = newValue;
                break;
            case "surnamePref":
                surname = newValue;
                break;
            case "emailPref":
                email = newValue;
                break;
        }

        String tag_string_req = "updateuser";
        StringRequest strReq = getStringChangeUserSettings(username,name,surname,email);
        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    private StringRequest getStringChangeUserSettings(final String username, final String name, final String surname, final String email) {
        return new StringRequest(Request.Method.POST, AppConfig.REST_UPDATE_USER, response -> {
            Log.d(TAG, "Change user settings: " + response);

            try {
                JSONObject jObj = new JSONObject(response);
                boolean error = jObj.getBoolean("error");
                if (!error) {
                    ((SettingsActivity) getActivity()).showMessage(getResources().getString(R.string.txt_success_changesett));
                    JSONObject tmpuser = jObj.getJSONObject("user");

                    JSONArray jSubs = tmpuser.getJSONArray("subs");
                    boolean isPremium = false;
                    boolean isAdFree = false;

                    if(jSubs.length() > 0){
                        for(int i = 0; i < jSubs.length();i++) {
                            if(jSubs.getJSONObject(i).getString("productId").contains("extra_functions")){
                                isPremium = true;
                            }

                            if(jSubs.getJSONObject(i).getString("productId").contains("no_ads")){
                                isAdFree = true;
                            }
                        }
                    }

                    ((SettingsActivity) getActivity()).session.addUser(tmpuser.getString("id"), tmpuser.getString("username"), tmpuser.getString("name"), tmpuser.getString("surname"), tmpuser.getString("email"), tmpuser.getString("status"), user.get("providerType"), tmpuser.getString("created_at"), tmpuser.getString("updated_at"), tmpuser.getString("lastlogin_at"), tmpuser.getString("accesskey"),isPremium,isAdFree);

                } else {
                    String errorMsg = jObj.getString("error_msg");
                    FirebaseCrashlytics.getInstance().log("Error getting user settings (Server returned error): " + errorMsg);
                    ((SettingsActivity) getActivity()).showMessage(getResources().getString(R.string.txt_errormsg_changesettings));
                }

            } catch (JSONException e) {
                FirebaseCrashlytics.getInstance().log("JSONException caught");
                FirebaseCrashlytics.getInstance().recordException(e);
            } finally {
                updatePrefs();
            }

            ((SettingsActivity) getActivity()).hideDialog();

        }, error -> {
            FirebaseCrashlytics.getInstance().log("Error getting user settings: " + error.getMessage());
            ((SettingsActivity) getActivity()).showMessage(getString(R.string.errormsg_couldnotretrieve));
            ((SettingsActivity) getActivity()).hideDialog();
            updatePrefs();
        }) {

            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<>();
                params.put("uid", user.get(SessionManager.KEY_UID));
                params.put("token", user.get(SessionManager.TOKEN));
                params.put("username", username);
                params.put("name", name);
                params.put("surname", surname);
                params.put("email", email);

                return params;
            }
        };
    }

}
