package org.deke.risk.riskahead;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.util.Patterns;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
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.JSONException;
import org.json.JSONObject;

import com.android.volley.Request.Method;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;

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

public class LoginActivity extends AppCompatActivity implements FacebookButtonFragment.OnFragmentInteractionListener, GooglePlusButtonFragment.OnFragmentInteractionListener, TwitterButtonFragment.OnFragmentInteractionListener{

    private final static String TAG = LoginActivity.class.getSimpleName();
    private final static String EXTRA_MESSAGE = "org.deke.risk.riskahead.MESSAGE";
    private final static String mActivityTitle = "RiskAhead";

    private String msg_intent;

    private Button btn_login;
    private TextView input_email;
    private TextView input_username;
    private TextView input_password;
    private TextView btn_requestPW;

    private ProgressDialog pDialog;
    private SessionManager session;

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

        session = new SessionManager(getApplicationContext());

        pDialog = new ProgressDialog(this);
        pDialog.setMessage("Sending data...");
        pDialog.setCancelable(false);

        Intent intent = getIntent();
        msg_intent = intent.getStringExtra(LoginActivity.EXTRA_MESSAGE);

        if(msg_intent.equals("login")){
            initLoginView();
        }else if(msg_intent.equals("register")){
            initRegisterView();
        }

        initSocialLoginButtons();
        initMyLoginButton();
    }

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

        input_email = (TextView) findViewById(R.id.input_register_email);
        input_password = (TextView) findViewById(R.id.input_register_password);
        btn_requestPW = (TextView) findViewById(R.id.lbl_login_resendPW);

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

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

        btn_requestPW.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onRequestNewPasswordClick(v);
            }
        });
    }

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

        input_username = (TextView) findViewById(R.id.input_register_name);
        input_email = (TextView) findViewById(R.id.input_register_email);
        input_password = (TextView) findViewById(R.id.input_register_password);

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

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

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

    private void initSocialLoginButtons() {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FacebookButtonFragment fragmentFB = new FacebookButtonFragment();
        GooglePlusButtonFragment fragmentGP = new GooglePlusButtonFragment();

        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(R.id.frag_login_btnGP, fragmentGP);
        transaction.commit();
    }

    private void initMyLoginButton() {
        btn_login = (Button) findViewById(R.id.btn_register);
        btn_login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (v.getId() == R.id.btn_register) {
                    String email = input_email.getText().toString();
                    String password = input_password.getText().toString();

                    if (msg_intent.equals("login")) {
                        if (input_password.getError() != null || input_email.getError() != null) {
                            showMessage(getString(R.string.error_validation));
                        } else {
                            showDialog();
                            performLogin(email, password);
                        }
                    } else if (msg_intent.equals("register")) {
                        String name = input_username.getText().toString();
                        if (input_password.getError() != null || input_email.getError() != null || input_username.getError() != null) {
                            showMessage(getString(R.string.error_validation));
                        } else {
                            showDialog();
                            performRegistration(name, email, password);
                        }
                    }
                }
            }
        });
    }

    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 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,
                    MainActivity.class);
            intent.putExtra(EXTRA_MESSAGE, "Social Media Login");
            startActivity(intent);
            finish();
        }

        String tag_string_req = "sociallogin";
        session.removeUser();
        showDialog();
        StringRequest strReq = getStringRequestSocialMediaLogin(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()){
            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, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        performRequestNewPassword();
                    }
                })
                .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int 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 StringRequest getStringRequestSocialMediaLogin(final String key, final String providerType, final String username, final String email) {
        return new StringRequest(Method.POST,AppConfig.URL_ENCRYPTED, new Response.Listener<String>() {

            @Override
            public void onResponse(String 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 username = user.getString("username");
                        String name = user.getString("name");
                        String surname = user.getString("surname");
                        String email = 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 providerType = user.getString("providerType");
                        String token = user.getString("accesskey");

                        session.addUser(id, username, name, surname, email, status, providerType, created_at, updated_at, lastlogin_at, token);

                        Intent intent = new Intent(
                                LoginActivity.this,
                                MainActivity.class);
                        intent.putExtra(EXTRA_MESSAGE, "Social Media Login");
                        startActivity(intent);
                        finish();
                    } else {
                        String errorMsg = jObj.getString("error_msg");
                        Log.e(TAG, "Error at social media login (Server returned error): " + errorMsg);
                        Toast.makeText(getApplicationContext(),errorMsg, Toast.LENGTH_LONG).show();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Social Media Login Error: " + error.getMessage());
                Toast.makeText(getApplicationContext(),
                        error.getMessage(), Toast.LENGTH_LONG).show();
                hideDialog();
            }
        }) {

            @Override
            protected Map<String, String> getParams() {
                // Posting params to register url
                Map<String, String> params = new HashMap<>();
                params.put("tag", "sociallogin");
                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.URL_ENCRYPTED, new Response.Listener<String>() {

            @Override
            public void onResponse(String 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 email = 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";

                        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, new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog, int 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, new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog, int which) {
                                        }
                                    })
                                    .setIcon(android.R.drawable.ic_dialog_alert)
                                    .show();
                        }else {
                            session.addUser(id, username, name, surname, email, status, providerType, created_at, updated_at, lastlogin_at, token);

                            session.setLogin(true);
                            hideDialog();

                            Intent intent = new Intent(LoginActivity.this, MainActivity.class);
                            startActivity(intent);
                            finish();
                        }
                    } else {
                        String errorMsg = jObj.getString("error_msg");
                        Log.e(TAG, "Error at login (Server returned error): " + errorMsg);
                        Toast.makeText(getApplicationContext(), errorMsg, Toast.LENGTH_LONG).show();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Login Error: " + error.getMessage());
                Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
                hideDialog();
            }
        }) {

            @Override
            protected Map<String, String> getParams() {
                // Posting parameters to login url
                Map<String, String> params = new HashMap<>();
                params.put("tag", "login");
                params.put("email", email);
                params.put("password", password);

                return params;
            }
        };
    }

    private StringRequest getStringRequestRegisterUser(final String username, final String email, final String password) {
        return new StringRequest(Method.POST, AppConfig.URL_ENCRYPTED, new Response.Listener<String>() {

                @Override
                public void onResponse(String response) {
                    Log.d(TAG, "Register Response: " + response);
                    hideDialog();

                    try {
                        JSONObject jObj = new JSONObject(response);
                        boolean error = jObj.getBoolean("error");
                        if (!error) {
                            new AlertDialog.Builder(LoginActivity.this)
                                    .setTitle(getString(R.string.alert_accregistration_title))
                                    .setMessage(getString(R.string.alert_accregistration_text))
                                    .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                                        public void onClick(DialogInterface dialog, int which) {
                                            Intent intent = new Intent(
                                                    LoginActivity.this,
                                                    LoginActivity.class);
                                            intent.putExtra(EXTRA_MESSAGE, "login");
                                            startActivity(intent);
                                            finish();
                                        }
                                    })
                                    .setIcon(android.R.drawable.ic_dialog_alert)
                                    .show();
                        } else {
                            String errorMsg = jObj.getString("error_msg");
                            Toast.makeText(getApplicationContext(),
                                    errorMsg, Toast.LENGTH_LONG).show();
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }, new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.e(TAG, "Registration Error: " + error.getMessage());
                    Toast.makeText(getApplicationContext(),
                            error.getMessage(), Toast.LENGTH_LONG).show();
                    hideDialog();
                }
            }) {

                @Override
                protected Map<String, String> getParams() {
                    // Posting params to register url
                    Map<String, String> params = new HashMap<>();
                    params.put("tag", "register");
                    params.put("username", username);
                    params.put("email", email);
                    params.put("password", password);

                    return params;
                }
            };
    }

    private StringRequest getStringRequestResetPW(final String email) {
        return new StringRequest(Method.POST, AppConfig.URL_ENCRYPTED, new Response.Listener<String>() {

            @Override
            public void onResponse(String 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");
                        Toast.makeText(getApplicationContext(),
                                errorMsg, Toast.LENGTH_LONG).show();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "E-Mail pw resend Error: " + error.getMessage());
                Toast.makeText(getApplicationContext(),
                        error.getMessage(), Toast.LENGTH_LONG).show();
                hideDialog();
            }
        }) {

            @Override
            protected Map<String, String> getParams() {
                // Posting params to register url
                Map<String, String> params = new HashMap<String, String>();
                params.put("tag", "requestpwreset");
                params.put("email", email);

                return params;
            }
        };
    }

    private StringRequest getStringRequestActivationLinkUser(final String email) {
        return new StringRequest(Method.POST, AppConfig.URL_ENCRYPTED, new Response.Listener<String>() {

            @Override
            public void onResponse(String 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");
                        Toast.makeText(getApplicationContext(),
                                errorMsg, Toast.LENGTH_LONG).show();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "E-Mail pw resend Error: " + error.getMessage());
                Toast.makeText(getApplicationContext(),
                        error.getMessage(), Toast.LENGTH_LONG).show();
                hideDialog();
            }
        }) {

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

                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("https://www.riskahead.net/about/"));
            startActivity(browserIntent);
        }else if((id == R.id.menu_action_help)){
            Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.riskahead.net/contact/"));
            startActivity(browserIntent);
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == GooglePlusButtonFragment.RC_SIGN_IN) {
            GooglePlusButtonFragment fragment = (GooglePlusButtonFragment) getSupportFragmentManager().findFragmentById(R.id.frag_login_btnGP);
            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);
        }

        Log.d("Test", "GOT ACTIVITY RESULT!!!:" + requestCode + " : " + resultCode);
    }
}
