package org.deke.risk.riskahead;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import com.google.android.material.textfield.TextInputLayout;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import androidx.core.content.ContextCompat;
import androidx.appcompat.app.AppCompatActivity;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.util.Patterns;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import org.deke.risk.riskahead.fragment.FacebookButtonFragment;
import org.deke.risk.riskahead.fragment.GooglePlusButtonFragment;
import org.deke.risk.riskahead.fragment.TwitterButtonFragment;
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.TextValidator;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.android.volley.Request.Method;
import com.android.volley.toolbox.StringRequest;
import com.beardedhen.androidbootstrap.BootstrapButton;
import com.google.firebase.crashlytics.FirebaseCrashlytics;

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 LoginActivity extends AppCompatActivity implements FacebookButtonFragment.OnFragmentInteractionListener, GooglePlusButtonFragment.OnFragmentInteractionListener, TwitterButtonFragment.OnFragmentInteractionListener{
    private final static String TAG = LoginActivity.class.getSimpleName();

    private TextView input_email;
    private TextView input_username;
    private TextView input_password;

    private TextInputLayout inputLayoutEmail;
    private TextInputLayout inputLayoutPassword;

    private ProgressDialog pDialog;
    private SessionManager session;

    static boolean active = false;

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

        session = new SessionManager(getApplicationContext());

        initProgressDialog();
        handleIntentAndInitView();

        initSocialLoginButtons();
        checkIfVersionSupported();
    }

    @Override
    protected void onResume(){
        super.onResume();
        isNetworkAvailable();
        checkForMaintenance();

        SessionManager session = new SessionManager(getApplicationContext());
        if (session.isLoggedIn()) {
            Log.d(TAG,"User found in sharedPrefs and is therefore logged in. Continue to internal Area.");
            Intent intent = new Intent(LoginActivity.this, MapsActivity.class);
            startActivity(intent);
            finish();
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        active = true;
    }

    @Override
    public void onStop() {
        super.onStop();
        active = false;
    }

    public void isNetworkAvailable() {
        NetworkInfo activeNetworkInfo = null;

        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        if(connectivityManager != null){
            activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        }else{
            FirebaseCrashlytics.getInstance().log("Could not get connectivityManager");
        }

        if(activeNetworkInfo == null){
            new AlertDialog.Builder(this)
                    .setTitle(getString(R.string.alert_internetconnection_title))
                    .setMessage(getString(R.string.alert_internetconnection_text))
                    .setCancelable(false)
                    .setNeutralButton(android.R.string.yes, (dialog, which) -> {
                       //todo What to do when no internet connection is available?
                    })
                    .setIcon(android.R.drawable.ic_dialog_alert)
                    .show();
        }
    }

    private void handleIntentAndInitView() {
        Intent intent = getIntent();
        String msg_intent = intent.getStringExtra(AppConfig.EXTRA_MESSAGE);

        if(msg_intent != null && msg_intent.equals(AppConfig.INTENT_LOGIN)){
            initLoginView();
        }else if((msg_intent == null) || msg_intent.equals(AppConfig.INTENT_REGISTER)){
            initRegisterView();
        }
    }

    private void initProgressDialog() {
        pDialog = new ProgressDialog(this);
        pDialog.setMessage(getString(R.string.progress_getdata_text));
        pDialog.setCancelable(false);
    }

    private void initLoginView() {
        setContentView(R.layout.activity_login);

        input_email = findViewById(R.id.input_register_email);
        inputLayoutEmail = findViewById(R.id.input_layout_email);

        input_password = findViewById(R.id.input_register_password);
        inputLayoutPassword = findViewById(R.id.input_layout_password);

        TextView btn_requestPW = findViewById(R.id.lbl_login_resendPW);

        BootstrapButton btn_gotoregistration = findViewById(R.id.btn_switchtoregistration);
        btn_gotoregistration.setOnClickListener(this::gotoRegister);

        BootstrapButton btn_login = findViewById(R.id.btn_login);
        btn_login.setOnClickListener((View v) -> {
                String email = input_email.getText().toString();
                String password = input_password.getText().toString();

                if (inputLayoutPassword.getError() != null || inputLayoutEmail.getError() != null) {
                    showMessage(getString(R.string.error_validation));
                } else {
                    showDialog();
                    performLogin(email, password);
                }
        });

        input_email.addTextChangedListener(new TextValidator(input_email, inputLayoutEmail, getApplicationContext()) {
            @Override
            public void validate(TextView textView, TextInputLayout inputLayout, String text) {
                if (!Patterns.EMAIL_ADDRESS.matcher(text).matches()) {
                    inputLayout.setError(getString(R.string.error_email));
                } else {
                    inputLayout.setErrorEnabled(false);
                }
            }
        });

        input_password.addTextChangedListener(new TextValidator(input_password, inputLayoutPassword,getApplicationContext()) {
            @Override
            public void validate(TextView textView, TextInputLayout inputLayout,String text) {
                if (text.length() < 5) {
                    inputLayout.setError(getString(R.string.error_password));
                } else {
                    inputLayout.setErrorEnabled(false);
                }
            }
        });

        btn_requestPW.setOnClickListener(this::onRequestNewPasswordClick);
    }

    private void initRegisterView() {
        setContentView(R.layout.activity_register);

        input_username = findViewById(R.id.input_register_name);
        final TextInputLayout inputLayoutUsername = findViewById(R.id.input_layout_username);
        input_email = findViewById(R.id.input_register_email);
        final TextInputLayout inputLayoutEmail = findViewById(R.id.input_layout_email);
        input_password = findViewById(R.id.input_register_password);
        final TextInputLayout inputLayoutPassword = findViewById(R.id.input_layout_password);
        BootstrapButton btn_login = findViewById(R.id.btn_register);
        TextView btn_switchtologin = findViewById(R.id.lbl_register_switchtologin);

        input_username.addTextChangedListener(new TextValidator(input_username, inputLayoutUsername, getApplicationContext()) {
            @Override
            public void validate(TextView textView, TextInputLayout inputLayout, String text) {
                if (text.trim().length() < 5) {
                    inputLayout.setError(getString(R.string.error_anytext));
                } else {
                    inputLayout.setErrorEnabled(false);
                }
            }
        });

        input_email.addTextChangedListener(new TextValidator(input_email, inputLayoutEmail, getApplicationContext()) {
            @Override
            public void validate(TextView textView, TextInputLayout inputLayout, String text) {
                if (!Patterns.EMAIL_ADDRESS.matcher(text).matches()) {
                    inputLayout.setError(getString(R.string.error_email));
                }else{
                    inputLayout.setErrorEnabled(false);
                }
            }
        });

        input_password.addTextChangedListener(new TextValidator(input_password, inputLayoutPassword, getApplicationContext()) {
            @Override
            public void validate(TextView textView, TextInputLayout inputLayout, String text) {
                if (text.length() < 5) {
                    inputLayout.setError(getString(R.string.error_password));
                } else {
                    inputLayout.setErrorEnabled(false);
                }
            }
        });

        btn_login.setOnClickListener(v -> {
            String email = input_email.getText().toString();
            String password = input_password.getText().toString();

            String name = input_username.getText().toString();
            if (inputLayoutPassword.getError() != null || inputLayoutEmail.getError() != null || inputLayoutUsername.getError() != null || input_email.getText().toString().trim().length() == 0 || input_username.getText().toString().trim().length() == 0 || input_password.getText().toString().trim().length() == 0) {
                showMessage(getString(R.string.error_validation));
            } else {
                showDialog();
                checkForUserAndPerformRegistration(name, email, password);
            }
        });

        btn_switchtologin.setOnClickListener(this::gotoLogin);
    }

    private void initSocialLoginButtons() {
        new FacebookButtonFragment();
        new GooglePlusButtonFragment();
    }

    private void checkForMaintenance() {
        String tag_string_req = "req_checkformaintenance";
        StringRequest strReq = getStringRequestCheckForMaintenance();
        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    private StringRequest getStringRequestCheckForMaintenance() {
        return new StringRequest(Method.POST, AppConfig.REST_CHECK_MAINTENANCE, response -> {
            Log.d(TAG, "Check for Maintenance Response: " + response);
            hideDialog();

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

                if (!error) {
                    if(jObj.getBoolean("maintenancemode")){
                        showMessage(jObj.getString("maintenancemsg"));
                    }
                }
            } catch (JSONException e) {
                FirebaseCrashlytics.getInstance().log("JSONException caught");
                FirebaseCrashlytics.getInstance().recordException(e);
            }
        }, error -> {
        }) {

            @Override
            protected Map<String, String> getParams() {
                return new HashMap<>();
            }
        };
    }

    public void gotoLogin(View view) {
        Intent intent = new Intent(this, LoginActivity.class);
        intent.putExtra(AppConfig.EXTRA_MESSAGE, AppConfig.INTENT_LOGIN);
        startActivity(intent);
    }

    public void gotoRegister(View view) {
        Intent intent = new Intent(this, LoginActivity.class);
        intent.putExtra(AppConfig.EXTRA_MESSAGE, AppConfig.INTENT_REGISTER);
        startActivity(intent);
    }

    private void checkIfVersionSupported() {
        String tag_string_req = "req_checkformaintenance";
        StringRequest strReq = getStringRequestCheckIfVersionSupported();
        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    private StringRequest getStringRequestCheckIfVersionSupported() {
        return new StringRequest(Method.POST, AppConfig.REST_CHECK_VERSION, response -> {
            Log.d(TAG, "Check Version Response: " + response);
            hideDialog();

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

                if (!error) {
                    if(!jObj.getBoolean("supported")){
                        showNotSupportedDialog();
                    }else if(!jObj.getBoolean("recommended")){
                        showNotRecommendDialog();
                    }
                }
            } catch (JSONException e) {
                FirebaseCrashlytics.getInstance().log("JSONException caught");
                FirebaseCrashlytics.getInstance().recordException(e);
            }
        }, error -> {
        }) {

            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<>();
                int versionCode = 99;

                try {
                    versionCode = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
                } catch (PackageManager.NameNotFoundException e) {
                    FirebaseCrashlytics.getInstance().log("JSONException caught");
                    FirebaseCrashlytics.getInstance().recordException(e);
                }

                params.put("version", Integer.toString(versionCode));
                return params;
            }
        };
    }

    private void showNotSupportedDialog() {
        new AlertDialog.Builder(LoginActivity.this)
                .setTitle(getString(R.string.alert_notsupported_title))
                .setMessage(getString(R.string.alert_notsupported_text))
                .setCancelable(false)
                .setPositiveButton(R.string.update, (dialog, which) -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + getPackageName()))))
                .setNegativeButton(R.string.exit, (dialog, which) -> {
                    Intent intent = new Intent(Intent.ACTION_MAIN);
                    intent.addCategory(Intent.CATEGORY_HOME);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    startActivity(intent);
                })
                .setIcon(android.R.drawable.ic_dialog_alert)
                .show();
    }

    private void showNotRecommendDialog() {
        new AlertDialog.Builder(LoginActivity.this)
                .setTitle(getString(R.string.alert_notrecommended_title))
                .setMessage(getString(R.string.alert_notrecommended_text))
                .setCancelable(false)
                .setPositiveButton(R.string.update, (dialog, which) -> startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + getPackageName()))))
                .setNegativeButton(R.string.later, (dialog, which) -> {

                })
                .setIcon(android.R.drawable.ic_dialog_alert)
                .show();
    }

    private void performLogin(final String email, final String password) {
        String tag_string_req = "req_login";
        StringRequest strReq = getStringRequestLogin(email, password);
        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    private void checkForUserAndPerformRegistration(final String username, final String email, final String password) {
        String tag_string_req = "req_checkregister";
        StringRequest strReq = getStringRequestCheckUserExists(username, email, password);
        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    private void performRegistration(final String username, final String email, final String password) {
        String tag_string_req = "req_register";
        StringRequest strReq = getStringRequestRegisterUser(username, email, password);
        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    public void handleSocialMediaLogin(final String key, final String providerType, final String username, final String email){
        if(session.isLoggedIn()){
            Intent intent = new Intent(
                    LoginActivity.this,
                    MapsActivity.class);
            intent.putExtra(AppConfig.EXTRA_MESSAGE, AppConfig.INTENT_SOCIALMEDIALOGIN);
            startActivity(intent);
            finish();
        }

        session.removeUser();
        showDialog();

        String tag_string_req = "socialloginrequest";
        StringRequest strReq = getStringRequestCheckSocialUserExists(key, providerType, username, email);
        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    public void onRequestNewPasswordClick(View view){
        if((input_email.getText() != null && input_email.getText().toString().isEmpty()) || (inputLayoutEmail.getError() != null)){
            showMessage(getString(R.string.message_enteremail));
            return;
        }

        new AlertDialog.Builder(LoginActivity.this)
                .setTitle(getString(R.string.alert_passwordreset_title))
                .setMessage(getString(R.string.alert_passwordreset_text))
                .setPositiveButton(android.R.string.yes, (dialog, which) -> performRequestNewPassword())
                .setNegativeButton(android.R.string.no, (dialog, which) -> {
                    // do nothing
                })
                .setIcon(android.R.drawable.ic_dialog_alert)
                .show();
    }

    private void performRequestNewPassword() {
        String tag_string_req = "requestpwreset";
        StringRequest strReq = getStringRequestResetPW(input_email.getText().toString());
        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    private void performSocialMediaLogin(final String key, final String providerType, final String username, final String email){
        String tag_string_req = "sociallogin";
        StringRequest strReq = getStringRequestSocialMediaLogin( key,  providerType,  username,  email);
        AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    private StringRequest getStringRequestSocialMediaLogin(final String key, final String providerType, final String username, final String email) {
        return new StringRequest(Method.POST,AppConfig.REST_LOGIN_SOCIAL, response -> {
            Log.d(TAG, "Social Media Login Response: " + response);
            hideDialog();

            try {
                JSONObject jObj = new JSONObject(response);
                boolean error = jObj.getBoolean("error");
                if (!error) {
                    session.setLogin(true);

                    JSONObject user = jObj.getJSONObject("user");
                    String id = user.getString("id");
                    String username1 = user.getString("username");
                    String name = user.getString("name");
                    String surname = user.getString("surname");
                    String email1 = user.getString("email");
                    String status = user.getString("status");
                    String created_at = user.getString("created_at");
                    String updated_at = user.getString("updated_at");
                    String lastlogin_at = user.getString("lastlogin_at");
                    String providerType1 = user.getString("providerType");
                    String token = user.getString("accesskey");

                    JSONArray jSubs = user.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;
                            }
                        }
                    }

                    session.addUser(id, username1, name, surname, email1, status, providerType1, created_at, updated_at, lastlogin_at, token,isPremium,isAdFree);

                    Intent intent = new Intent(
                            LoginActivity.this,
                            MapsActivity.class);
                    intent.putExtra(AppConfig.EXTRA_MESSAGE, AppConfig.INTENT_SOCIALMEDIALOGIN);
                    startActivity(intent);
                    finish();
                } else {
                    String errorMsg = jObj.getString("error_msg");
                    FirebaseCrashlytics.getInstance().log("Error at social media login (Server returned error): " + errorMsg);
                    Toast.makeText(getApplicationContext(), getResources().getString(R.string.txt_errormsg_login)+getResources().getString(R.string.txt_errormsg_suffix), Toast.LENGTH_LONG).show();
                }
            } catch (JSONException e) {
                FirebaseCrashlytics.getInstance().log("JSONException caught");
                FirebaseCrashlytics.getInstance().recordException(e);
            }

        }, error -> {
            FirebaseCrashlytics.getInstance().log("Social Media Login Error: " + error.getMessage());
            Toast.makeText(getApplicationContext(), getResources().getString(R.string.txt_errormsg_login)+getResources().getString(R.string.txt_errormsg_suffix), Toast.LENGTH_LONG).show();
            hideDialog();
        }) {

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

                return params;
            }

        };
    }

    private StringRequest getStringRequestLogin(final String email, final String password) {
        return new StringRequest(Method.POST, AppConfig.REST_LOGIN, response -> {
            Log.d(TAG, "Login Response: " + response);
            hideDialog();

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

                if (!error) {
                    JSONObject user = jObj.getJSONObject("user");
                    String id = user.getString("id");
                    String username = user.getString("username");
                    String name = user.getString("name");
                    String surname = user.getString("surname");
                    String email1 = user.getString("email");
                    String status = user.getString("status");
                    String created_at = user.getString("created_at");
                    String updated_at = user.getString("updated_at");
                    String lastlogin_at = user.getString("lastlogin_at");
                    String token = user.getString("accesskey");
                    String providerType = "local";

                    JSONArray jSubs = user.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;
                            }
                        }
                    }

                    if(status.equals("0")){
                        new AlertDialog.Builder(LoginActivity.this)
                                .setTitle(getString(R.string.alert_accactivation_title))
                                .setMessage(getString(R.string.alert_accactivation_text))
                                .setPositiveButton(android.R.string.yes, (dialog, which) -> {
                                    String tag_string_req = "resendactivationusermail";

                                    StringRequest strReq = getStringRequestActivationLinkUser(input_email.getText().toString());

                                    AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
                                    showMessage(getString(R.string.alert_accactivation_confirmation));
                                })
                                .setNegativeButton(android.R.string.no, (dialog, which) -> {
                                })
                                .setIcon(android.R.drawable.ic_dialog_alert)
                                .show();
                    }else {
                        session.addUser(id, username, name, surname, email1, status, providerType, created_at, updated_at, lastlogin_at, token, isPremium, isAdFree);
                        session.setLogin(true);

                        hideDialog();

                        Intent intent = new Intent(LoginActivity.this, MapsActivity.class);
                        startActivity(intent);
                        finish();
                    }
                } else {
                    String errorMsg = jObj.getString("error_msg");
                    FirebaseCrashlytics.getInstance().log("Error at login (Server returned error): " + errorMsg);
                    Toast.makeText(getApplicationContext(), getResources().getString(R.string.txt_errormsg_login), Toast.LENGTH_LONG).show();
                }
            } catch (JSONException e) {
                FirebaseCrashlytics.getInstance().log("JSONException caught");
                FirebaseCrashlytics.getInstance().recordException(e);
            }
        }, error -> {
            FirebaseCrashlytics.getInstance().log("Login Error: " + error.getMessage());
            Toast.makeText(getApplicationContext(), getResources().getString(R.string.txt_errormsg_login), Toast.LENGTH_LONG).show();
            hideDialog();
        }) {

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

                return params;
            }
        };
    }

    private StringRequest getStringRequestCheckUserExists(final String username, final String email, final String password) {
        return new StringRequest(Method.POST, AppConfig.REST_USEREXISTS, response -> {
            Log.d(TAG, "Check User Exists Response: " + response);
            hideDialog();

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

                    if(jObj.getInt("exists") == 1){
                       showMessage("Registration failed. Username and/or E-Mail already taken");
                    }else{
                        createAndShowPrivacyDialog(username, email, password);
                    }



                } else {
                    String errorMsg = jObj.getString("error_msg");
                    FirebaseCrashlytics.getInstance().log("Error occured: "+errorMsg);
                    Toast.makeText(getApplicationContext(), getResources().getString(R.string.txt_errormsg_register), Toast.LENGTH_LONG).show();
                }
            } catch (JSONException e) {
                FirebaseCrashlytics.getInstance().log("Exception caught");
                FirebaseCrashlytics.getInstance().recordException(e);
            }
        }, error -> {
            FirebaseCrashlytics.getInstance().log("Registration Error: " + error.getMessage());
            Toast.makeText(getApplicationContext(),
                    getResources().getString(R.string.txt_errormsg_register), Toast.LENGTH_LONG).show();
            hideDialog();
        }) {

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

                    return params;
                }
            };
    }

    private StringRequest getStringRequestCheckSocialUserExists(final String key, final String providerType, final String username, final String email) {
        return new StringRequest(Method.POST, AppConfig.REST_USEREXISTS, response -> {
            Log.d(TAG, "Check Social User Exists Response: " + response);
            hideDialog();

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

                    if(jObj.getInt("exists") == 1){
                        performSocialMediaLogin( key,providerType, username, email);
                    }else{
                        createAndShowPrivacyDialogForSocialUser( key,providerType, username, email);
                    }

                } else {
                    String errorMsg = jObj.getString("error_msg");
                    FirebaseCrashlytics.getInstance().log("Error occured: "+errorMsg);
                    Toast.makeText(getApplicationContext(), getResources().getString(R.string.txt_errormsg_register), Toast.LENGTH_LONG).show();
                }
            } catch (JSONException e) {
                FirebaseCrashlytics.getInstance().log("JSONException caught");
                FirebaseCrashlytics.getInstance().recordException(e);
            }
        }, error -> {
            FirebaseCrashlytics.getInstance().log("Registration Error: " + error.getMessage());
            Toast.makeText(getApplicationContext(),
                    getResources().getString(R.string.txt_errormsg_register), Toast.LENGTH_LONG).show();
            hideDialog();
        }) {

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

                return params;
            }
        };
    }

    private void createAndShowPrivacyDialogForSocialUser(final String key, final String providerType, final String username, final String email) {
        final TextView privacyText = new TextView(LoginActivity.this);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT);


        privacyText.setLayoutParams(lp);
        privacyText.setText(R.string.txt_register_privacy);
        privacyText.setMovementMethod(LinkMovementMethod.getInstance());
        privacyText.setPadding(5, 10, 5, 10);

        CheckBox privacyCheckbox = new CheckBox(getApplicationContext());
        privacyCheckbox.setText(R.string.txt_register_privacy_text);
        privacyCheckbox.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.md_black_1000));
        final float scale = this.getResources().getDisplayMetrics().density;
        privacyCheckbox.setPadding(privacyCheckbox.getPaddingLeft() + (int) (10.0f * scale + 0.5f),
                privacyCheckbox.getPaddingTop() + 5,
                privacyCheckbox.getPaddingRight(),
                privacyCheckbox.getPaddingBottom());
        privacyCheckbox.setButtonDrawable(Resources.getSystem().getIdentifier("btn_check_holo_light", "drawable", "android"));


        LinearLayout layout = new LinearLayout(LoginActivity.this);
        layout.setOrientation(LinearLayout.VERTICAL);
        layout.addView(privacyText);
        layout.addView(privacyCheckbox);

        AlertDialog.Builder builder =  new AlertDialog.Builder(LoginActivity.this)
                .setTitle(R.string.txt_register_privacy_title)
                .setPositiveButton(android.R.string.yes, (dialog, which) -> performSocialMediaLogin(key, providerType, username, email))
                .setNegativeButton(android.R.string.no, (dialog, which) -> {
                })
                .setIcon(R.drawable.logo_380);

        final AlertDialog dialog = builder.create();

        privacyCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> {
            if (isChecked) {
                dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
            } else {
                dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
            }
        });

        dialog.setView(layout, 30, 30, 30, 30);
        dialog.show();


        dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
    }

    private void createAndShowPrivacyDialog(final String username, final String email, final String password) {
        final TextView privacyText = new TextView(LoginActivity.this);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT);


        privacyText.setLayoutParams(lp);
        privacyText.setText(R.string.txt_register_privacy);
        privacyText.setMovementMethod(LinkMovementMethod.getInstance());
        privacyText.setPadding(5, 10, 5, 10);

        CheckBox privacyCheckbox = new CheckBox(getApplicationContext());
        privacyCheckbox.setText(R.string.txt_register_privacy_text);
        privacyCheckbox.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.md_black_1000));
        final float scale = this.getResources().getDisplayMetrics().density;
        privacyCheckbox.setPadding(privacyCheckbox.getPaddingLeft() + (int) (10.0f * scale + 0.5f),
                privacyCheckbox.getPaddingTop() + 5,
                privacyCheckbox.getPaddingRight(),
                privacyCheckbox.getPaddingBottom());
        privacyCheckbox.setButtonDrawable(Resources.getSystem().getIdentifier("btn_check_holo_light", "drawable", "android"));


        LinearLayout layout = new LinearLayout(LoginActivity.this);
        layout.setOrientation(LinearLayout.VERTICAL);
        layout.addView(privacyText);
        layout.addView(privacyCheckbox);

        AlertDialog.Builder builder =  new AlertDialog.Builder(LoginActivity.this)
                .setTitle(R.string.txt_register_privacy_title)
                .setPositiveButton(android.R.string.yes, (dialog, which) -> performRegistration(username, email, password))
                .setNegativeButton(android.R.string.no, (dialog, which) -> {
                })
                .setIcon(R.drawable.logo_380);

        final AlertDialog dialog = builder.create();

        privacyCheckbox.setOnCheckedChangeListener((buttonView, isChecked) -> {
            if (isChecked) {
                dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
            } else {
                dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
            }
        });

        dialog.setView(layout, 30, 30, 30, 30);
        dialog.show();

        dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
    }

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

            try {
                JSONObject jObj = new JSONObject(response);
                boolean error = jObj.getBoolean("error");
                if (!error) {
                    showMessage(getString(R.string.alert_passwordreset_confirmation));
                } else {
                    String errorMsg = jObj.getString("error_msg");
                    FirebaseCrashlytics.getInstance().log("Reset PW returned error value: "+errorMsg);
                    Toast.makeText(getApplicationContext(),
                            getResources().getString(R.string.txt_errormsg_getpwreset), Toast.LENGTH_LONG).show();
                }
            } catch (JSONException e) {
                FirebaseCrashlytics.getInstance().log("JSONException caught");
                FirebaseCrashlytics.getInstance().recordException(e);
            }

        }, error -> {
            FirebaseCrashlytics.getInstance().log("E-Mail pw resend Error: " + error.getMessage());
            Toast.makeText(getApplicationContext(),
                    getResources().getString(R.string.txt_errormsg_getpwreset), Toast.LENGTH_LONG).show();
            hideDialog();
        }) {

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

                return params;
            }
        };
    }

    private StringRequest getStringRequestActivationLinkUser(final String email) {
        return new StringRequest(Method.POST, AppConfig.REST_SENDACTIVATIONMAIL, response -> {
            Log.d(TAG, "Resend E-Mail Response: " + response);
            hideDialog();

            try {
                JSONObject jObj = new JSONObject(response);
                boolean error = jObj.getBoolean("error");
                if (error) {
                    String errorMsg = jObj.getString("error_msg");
                    FirebaseCrashlytics.getInstance().log("Resend E-Mail returned error value: "+errorMsg);
                    Toast.makeText(getApplicationContext(),
                            getResources().getString(R.string.txt_errormsg_getactivationlink) + ":"+errorMsg, Toast.LENGTH_LONG).show();
                }
            } catch (JSONException e) {
                FirebaseCrashlytics.getInstance().log("JSONException caught");
                FirebaseCrashlytics.getInstance().recordException(e);
            }

        }, error -> {
            FirebaseCrashlytics.getInstance().log("E-Mail pw resend error: " + error.getMessage());
            Toast.makeText(getApplicationContext(),
                    getResources().getString(R.string.txt_errormsg_getactivationlink), Toast.LENGTH_LONG).show();
            hideDialog();
        }) {

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

                return params;
            }
        };
    }

    private StringRequest getStringRequestRegisterUser(final String username, final String email, final String password) {
        return new StringRequest(Method.POST, AppConfig.REST_REGISTER, response -> {
            Log.d(TAG, "Register Response: " + response);
            hideDialog();

            try {
                JSONObject jObj = new JSONObject(response);
                boolean error = jObj.getBoolean("error");
                if (!error && active) {
                    new AlertDialog.Builder(LoginActivity.this)
                            .setTitle(getString(R.string.alert_accregistration_title))
                            .setMessage(getString(R.string.alert_accregistration_text))
                            .setPositiveButton(android.R.string.yes, (dialog, which) -> {
                                Intent intent = new Intent(
                                        LoginActivity.this,
                                        LoginActivity.class);
                                intent.putExtra(AppConfig.EXTRA_MESSAGE, AppConfig.INTENT_LOGIN);
                                startActivity(intent);
                                finish();
                            })
                            .setIcon(android.R.drawable.ic_dialog_alert)
                            .show();
                } else if (error){
                    String errorMsg = jObj.getString("error_msg");
                    FirebaseCrashlytics.getInstance().log("Error occured: "+errorMsg);
                    Toast.makeText(getApplicationContext(), getResources().getString(R.string.txt_errormsg_register), Toast.LENGTH_LONG).show();
                }
            } catch (JSONException e) {
                FirebaseCrashlytics.getInstance().log("JSONException caught");
                FirebaseCrashlytics.getInstance().recordException(e);
            }
        }, error -> {
            FirebaseCrashlytics.getInstance().log("Registration Error: " + error.getMessage());
            Toast.makeText(getApplicationContext(),
                    getResources().getString(R.string.txt_errormsg_register), Toast.LENGTH_LONG).show();
            hideDialog();
        }) {

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

                return params;
            }
        };
    }


    public void showMessage(String statusText){
        Toast.makeText(this, statusText, Toast.LENGTH_LONG).show();
    }

    public void onFragmentInteraction(Uri uri){
    }

    private void showDialog() {
        if (!pDialog.isShowing())
            pDialog.show();
    }

    private void hideDialog() {
        if (pDialog.isShowing())
            pDialog.dismiss();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_common, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if((id == R.id.menu_action_exit)){
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_HOME);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
        }else if((id == R.id.menu_action_about)){
            Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(AppConfig.URL_ABOUT));
            startActivity(browserIntent);
        }else if((id == R.id.menu_action_help)){
            Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(AppConfig.URL_CONTACT));
            startActivity(browserIntent);
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.d(TAG, "testest");
        if (requestCode == GooglePlusButtonFragment.RC_SIGN_IN) {
            GooglePlusButtonFragment fragment = (GooglePlusButtonFragment) getSupportFragmentManager().findFragmentById(R.id.frag_login_btnGP);
            if(fragment != null) fragment.onActivityResult(requestCode, resultCode, data);
        }

        TwitterButtonFragment twitter_fragment = (TwitterButtonFragment) getSupportFragmentManager().findFragmentById(R.id.frag_login_btnTW);
        if (twitter_fragment != null) {
            twitter_fragment.onActivityResult(requestCode, resultCode, data);
        }

        FacebookButtonFragment facebook_fragment = (FacebookButtonFragment) getSupportFragmentManager().findFragmentById(R.id.frag_login_btnFB);
        if (facebook_fragment != null) {
            facebook_fragment.onActivityResult(requestCode, resultCode, data);
        }

    }

}
