package kr.co.icontrols.iotplatform;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoDevice;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUser;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.CognitoUserSession;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.AuthenticationContinuation;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.AuthenticationDetails;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.ChallengeContinuation;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.ChooseMfaContinuation;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.ForgotPasswordContinuation;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.MultiFactorAuthenticationContinuation;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.continuations.NewPasswordContinuation;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.handlers.AuthenticationHandler;
import com.amazonaws.mobileconnectors.cognitoidentityprovider.handlers.ForgotPasswordHandler;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.Scopes;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.Scope;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;

import java.util.List;
import java.util.Locale;
import java.util.Map;

import kr.co.icontrols.iotplatform.cognito.AppHelper;
import kr.co.icontrols.iotplatform.utils.CommonUtils;
import kr.co.icontrols.iotplatform.utils.SharedPrefUtil;

import static kr.co.icontrols.iotplatform.utils.CommonUtils.DebugLogOutput;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.DismissConnectDialog;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.ErrorLogOutput;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.ForceDismissConnectDialog;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.displayProgress;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.isEmailValid;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.setupUI;
import static kr.co.icontrols.iotplatform.utils.CommonUtils.showNotiMsg;
import static kr.co.icontrols.iotplatform.utils.Constants.RESULT_CHOOSE_MFA;
import static kr.co.icontrols.iotplatform.utils.Constants.RESULT_CONFIRM_SIGN_UP;
import static kr.co.icontrols.iotplatform.utils.Constants.RESULT_FORGOT_PASSWORD_CODE;
import static kr.co.icontrols.iotplatform.utils.Constants.RESULT_GOOGE_GET_AUTH_CODE;
import static kr.co.icontrols.iotplatform.utils.Constants.RESULT_LAUNCH_USER;
import static kr.co.icontrols.iotplatform.utils.Constants.RESULT_MFA;
import static kr.co.icontrols.iotplatform.utils.Constants.RESULT_NEW_PASSWORD;
import static kr.co.icontrols.iotplatform.utils.Constants.RESULT_SIGN_UP;
import static kr.co.icontrols.iotplatform.utils.SharedPrefUtil.AUTO_LOGIN;
import static kr.co.icontrols.iotplatform.utils.SharedPrefUtil.DEFAULT_AUTO_LOGIN;
import static kr.co.icontrols.iotplatform.utils.SharedPrefUtil.DEFAULT_LOGIN_TIME;
import static kr.co.icontrols.iotplatform.utils.SharedPrefUtil.DEFAULT_USER_ID;
import static kr.co.icontrols.iotplatform.utils.SharedPrefUtil.DEFAULT_USER_PASS;
import static kr.co.icontrols.iotplatform.utils.SharedPrefUtil.LOGIN_TIME;

public class LoginActivity extends AppCompatActivity implements View.OnClickListener {

    private final String TAG = "LoginActivity";

    private AlertDialog userDialog;
    private ProgressDialog waitDialog;

    // Screen fields
    private EditText inUsername;
    private EditText inPassword;

    //Continuations
    private MultiFactorAuthenticationContinuation multiFactorAuthenticationContinuation;
    private ForgotPasswordContinuation forgotPasswordContinuation;
    private NewPasswordContinuation newPasswordContinuation;
    private ChooseMfaContinuation mfaOptionsContinuation;

    // User Details
    private String username;
    private String password;

    //GOOGLE AUTH
    private GoogleSignInClient mGoogleSignInClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        setupUI(this, findViewById(R.id.layoutMain));

        initApp();

        ((CheckBox)findViewById(R.id.chkAutoLogin)).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                SharedPrefUtil.putBoolean(SharedPrefUtil.AUTO_LOGIN,b);
            }
        });

        if(SharedPrefUtil.getBoolean(AUTO_LOGIN,DEFAULT_AUTO_LOGIN)) {
            ((CheckBox)findViewById(R.id.chkAutoLogin)).setChecked(true);
            findCurrent();
        } else {
            //기존 세션을 가지고 있으면 강제 제거
            AppHelper.getPool().getUser(AppHelper.getPool().getCurrentUser().getUserId()).signOut();
        }

        // For sample only: make sure there is a valid server client ID.
        validateServerClientID();

        // [START configure_signin]
        // Configure sign-in to request offline access to the user's ID, basic
        // profile, and Google Drive. The first time you request a code you will
        // be able to exchange it for an access token and refresh token, which
        // you should store. In subsequent calls, the code will only result in
        // an access token. By asking for profile access (through
        // DEFAULT_SIGN_IN) you will also get an ID Token as a result of the
        // code exchange.
        String serverClientId = getString(R.string.google_auth_server_client_id);
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestScopes(new Scope(Scopes.EMAIL), new Scope(Scopes.PROFILE), new Scope(Scopes.OPEN_ID))
                .requestServerAuthCode(serverClientId)
                .requestEmail()
                .build();
        // [END configure_signin]

        mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
    }

    @Override
    protected void onPause() {
        ForceDismissConnectDialog();
        super.onPause();
    }

    @Override
    public void onClick(View v) {
        /*
        final View fv = v;
        fv.setEnabled(false);
        Timer buttonTimer = new Timer();
        buttonTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            fv.setEnabled(true);
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {

                        }
                    }
                });
            }
        }, 500);
        */

        switch (v.getId()) {
            case R.id.btnLogin:
                //기존 세션을 가지고 있으면 강제 제거
                AppHelper.getPool().getUser(AppHelper.getPool().getCurrentUser().getUserId()).signOut();
                logIn(v);
                break;
            case R.id.txtFindId:
                break;
            case R.id.txtFindPassword:
                forgotPassword(v);
                break;
            case R.id.txtSignUp:
                signUp(v);
                break;
            case R.id.btnLoginWithGoogle:
                getAuthCode();
                break;
        }
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        switch (requestCode) {
            case RESULT_GOOGE_GET_AUTH_CODE: {
                // [START get_auth_code]
                Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
                try {
                    GoogleSignInAccount account = task.getResult(ApiException.class);
                    String authCode = account.getServerAuthCode();

                    // Show signed-un UI
                    updateUI(account);
                } catch (ApiException e) {
                    ErrorLogOutput(TAG, "Sign-in failed : " + e);
                    updateUI(null);
                }
                // [END get_auth_code]
            }
            break;
            case RESULT_SIGN_UP:
                // Register user
                if(resultCode == RESULT_OK) {
                    String name = data.getStringExtra("name");
                    if (!name.isEmpty()) {
                        inUsername.setText(name);
                        inPassword.setText("");
                        inPassword.requestFocus();
                    }
                    String userPasswd = data.getStringExtra("password");
                    if (!userPasswd.isEmpty()) {
                        inPassword.setText(userPasswd);
                    }
                    if (!name.isEmpty() && !userPasswd.isEmpty()) {
                        // We have the user details, so sign in!
                        username = name;
                        password = userPasswd;
                        AppHelper.getPool().getUser(username).getSessionInBackground(authenticationHandler);
                    }
                }
                break;
            case RESULT_CONFIRM_SIGN_UP:
                // Confirm register user
                if(resultCode == RESULT_OK) {
                    String name = data.getStringExtra("name");
                    if (!name.isEmpty()) {
                        inUsername.setText(name);
                        inPassword.setText("");
                        inPassword.requestFocus();
                    }
                }
                break;
            case RESULT_FORGOT_PASSWORD_CODE:
                // Forgot password
                if(resultCode == RESULT_OK) {
                    String newPass = data.getStringExtra("newPass");
                    String code = data.getStringExtra("code");
                    if (newPass != null && code != null) {
                        if (!newPass.isEmpty() && !code.isEmpty()) {
                            displayProgress(LoginActivity.this,"","");//showWaitDialog("Setting new password...");
                            forgotPasswordContinuation.setPassword(newPass);
                            forgotPasswordContinuation.setVerificationCode(code);
                            forgotPasswordContinuation.continueTask();
                        }
                    }
                }
                break;
            case RESULT_LAUNCH_USER:
                // User
                if(resultCode == RESULT_OK) {
                    clearInput();
                    String name = data.getStringExtra("TODO");
                    if(name != null) {
                        if (!name.isEmpty()) {
                            name.equals("exit");
                            onBackPressed();
                        }
                    }
                }
                break;
            case RESULT_MFA:
                //MFA
                DismissConnectDialog(); //closeWaitDialog();
                if(resultCode == RESULT_OK) {
                    String code = data.getStringExtra("mfacode");
                    if(code != null) {
                        if (code.length() > 0) {
                            displayProgress(LoginActivity.this,"","");//showWaitDialog("Signing in...");
                            multiFactorAuthenticationContinuation.setMfaCode(code);
                            multiFactorAuthenticationContinuation.continueTask();
                        } else {
                            inPassword.setText("");
                            inPassword.requestFocus();
                        }
                    }
                }
                break;
            case RESULT_NEW_PASSWORD:
                //New password
                DismissConnectDialog(); //closeWaitDialog();
                Boolean continueSignIn = false;
                if (resultCode == RESULT_OK) {
                    continueSignIn = data.getBooleanExtra("continueSignIn", false);
                }
                if (continueSignIn) {
                    continueWithFirstTimeSignIn();
                }
                break;
            case RESULT_CHOOSE_MFA:
                // Choose MFA
                DismissConnectDialog(); //closeWaitDialog();
                if(resultCode == RESULT_OK) {
                    String option = data.getStringExtra("mfaOption");
                    if (option != null) {
                        if (option.length() > 0) {
                            DebugLogOutput(TAG, " -- Selected Option: " + option);
                            conitnueWithSelectedMfa(option);
                        } else {
                            inPassword.setText("");
                            inPassword.requestFocus();
                            Toast.makeText(LoginActivity.this,"Login cancelled",Toast.LENGTH_SHORT).show();
                            /*
                            TextView label = (TextView) findViewById(R.id.textViewUserPasswordMessage);
                            label.setText("Login cancelled");
                             */
                        }
                    }
                }
        }
    }

    // App methods
    // Register user - start process
    public void signUp(View view) {
        signUpNewUser();
    }

    // Login if a user is already present
    public void logIn(View view) {
        signInUser();
    }

    // Forgot password processing
    public void forgotPassword(View view) {
        forgotpasswordUser();
    }

    private void signUpNewUser() {
        Intent registerActivity = new Intent(this, SignUpInputActivity.class);
        startActivityForResult(registerActivity, RESULT_SIGN_UP);
    }

    private void signInUser() {
        username = inUsername.getText().toString().replace(" ","");

        if(username == null || username.length() < 1) {
            showNotiMsg(LoginActivity.this,"아이디를 입력해주세요.");
            return;
        } else if (!isEmailValid(username)) {
            showNotiMsg(LoginActivity.this,"이메일 형식을 입력해주세요.");
            return;
        }

        AppHelper.setUser(username);

        password = inPassword.getText().toString();
        if(password == null || password.length() < 1) {
            showNotiMsg(LoginActivity.this,"비밀번호를 입력해주세요.");
            return;
        }

        displayProgress(LoginActivity.this,"","");//showWaitDialog("Signing in...");
        AppHelper.getPool().getUser(username).getSessionInBackground(authenticationHandler);
    }

    private void forgotpasswordUser() {
        username = inUsername.getText().toString();
        if(username == null) {
            Toast.makeText(LoginActivity.this,inUsername.getHint()+" cannot be empty",Toast.LENGTH_SHORT).show();
            /*
            TextView label = (TextView) findViewById(R.id.textViewUserIdMessage);
            label.setText(inUsername.getHint()+" cannot be empty");
            inUsername.setBackground(getDrawable(R.drawable.text_border_error));
            */
            return;
        }

        if(username.length() < 1) {
            Toast.makeText(LoginActivity.this,inUsername.getHint()+" cannot be empty",Toast.LENGTH_SHORT).show();
            /*
            TextView label = (TextView) findViewById(R.id.textViewUserIdMessage);
            label.setText(inUsername.getHint()+" cannot be empty");
            inUsername.setBackground(getDrawable(R.drawable.text_border_error));
            */
            return;
        }

        displayProgress(LoginActivity.this,"","");//showWaitDialog("");
        AppHelper.getPool().getUser(username).forgotPasswordInBackground(forgotPasswordHandler);
    }

    private void getForgotPasswordCode(ForgotPasswordContinuation forgotPasswordContinuation) {
        ErrorLogOutput(TAG, "call getForgotPasswordCode (ForgotPasswordActivity)");
        this.forgotPasswordContinuation = forgotPasswordContinuation;
        Intent intent = new Intent(this, ForgotPasswordActivity.class);
        intent.putExtra("destination",forgotPasswordContinuation.getParameters().getDestination());
        intent.putExtra("deliveryMed", forgotPasswordContinuation.getParameters().getDeliveryMedium());
        startActivityForResult(intent, RESULT_FORGOT_PASSWORD_CODE);
    }

    private void mfaAuth(MultiFactorAuthenticationContinuation continuation) {
        ErrorLogOutput(TAG, "call mfaAuth (Do noting)");
        /*
        multiFactorAuthenticationContinuation = continuation;
        Intent mfaActivity = new Intent(this, MFAActivity.class);
        mfaActivity.putExtra("mode", multiFactorAuthenticationContinuation.getParameters().getDeliveryMedium());
        startActivityForResult(mfaActivity, RESULT_MFA);
         */
    }

    private void firstTimeSignIn() {
        ErrorLogOutput(TAG, "call firstTimeSignIn (NewPasswordActivity)");
        Intent newPasswordActivity = new Intent(this, NewPasswordActivity.class);
        startActivityForResult(newPasswordActivity, RESULT_NEW_PASSWORD);
    }

    private void selectMfaToSignIn(List<String> options, Map<String, String> parameters) {
        ErrorLogOutput(TAG, "call selectMfaToSignIn (Do noting)");
        /*
        Intent chooseMfaActivity = new Intent(this, ChooseMFA.class);
        AppHelper.setMfaOptionsForDisplay(options, parameters);
        startActivityForResult(chooseMfaActivity, RESULT_CHOOSE_MFA);
         */
    }

    private void conitnueWithSelectedMfa(String option) {
        // mfaOptionsContinuation.setChallengeResponse("ANSWER", option);
        mfaOptionsContinuation.setMfaOption(option);
        mfaOptionsContinuation.continueTask();
    }

    private void continueWithFirstTimeSignIn() {
        newPasswordContinuation.setPassword(AppHelper.getPasswordForFirstTimeLogin());
        Map <String, String> newAttributes = AppHelper.getUserAttributesForFirstTimeLogin();
        if (newAttributes != null) {
            for(Map.Entry<String, String> attr: newAttributes.entrySet()) {
                DebugLogOutput(TAG, String.format(" -- Adding attribute: %s, %s", attr.getKey(), attr.getValue()));
                newPasswordContinuation.setUserAttribute(attr.getKey(), attr.getValue());
            }
        }
        try {
            newPasswordContinuation.continueTask();
        } catch (Exception e) {
            DismissConnectDialog(); //closeWaitDialog();
            showNotiMsg(LoginActivity.this,"로그인에 실패하였습니다.");
            //Toast.makeText(LoginActivity.this,"Sign-in failed",Toast.LENGTH_SHORT).show();
            /*
            TextView label = (TextView) findViewById(R.id.textViewUserIdMessage);
            label.setText("Sign-in failed");
            inPassword.setBackground(getDrawable(R.drawable.text_border_error));

            label = (TextView) findViewById(R.id.textViewUserIdMessage);
            label.setText("Sign-in failed");
            inUsername.setBackground(getDrawable(R.drawable.text_border_error));
            */
            //showDialogMessage("Sign-in failed", AppHelper.formatException(e));
        }
    }

    private void confirmUser() {
        ErrorLogOutput(TAG, "call confirmUser (SignUpCertificationActivity)");
        Intent confirmActivity = new Intent(this, SignUpCertificationActivity.class);
        confirmActivity.putExtra("source","main");
        startActivityForResult(confirmActivity, RESULT_CONFIRM_SIGN_UP);

    }

    private void launchUser() {
        ErrorLogOutput(TAG, "call launchUser (MainActivity)");
        Intent userActivity = new Intent(this, MainActivity.class);
        userActivity.putExtra("name", username);
        startActivityForResult(userActivity, RESULT_LAUNCH_USER);
        finish();
    }

    private void findCurrent() {
        CognitoUser user = AppHelper.getPool().getCurrentUser();
        username = user.getUserId();
        if(username != null) {
            AppHelper.setUser(username);
            inUsername.setText(user.getUserId());
            user.getSessionInBackground(authenticationHandler);
        }
    }

    private void getUserAuthentication(AuthenticationContinuation continuation, String username) {
        if(username != null) {
            this.username = username;
            AppHelper.setUser(username);
        }
        if(this.password == null) {
            inUsername.setText(username);
            password = inPassword.getText().toString();
            if(password == null) {
                Toast.makeText(LoginActivity.this,inPassword.getHint()+" enter password",Toast.LENGTH_SHORT).show();
                /*
                TextView label = (TextView) findViewById(R.id.textViewUserPasswordMessage);
                label.setText(inPassword.getHint()+" enter password");
                inPassword.setBackground(getDrawable(R.drawable.text_border_error));
                */
                return;
            }

            if(password.length() < 1) {
                Toast.makeText(LoginActivity.this,inPassword.getHint()+" enter password",Toast.LENGTH_SHORT).show();
                /*
                TextView label = (TextView) findViewById(R.id.textViewUserPasswordMessage);
                label.setText(inPassword.getHint()+" enter password");
                inPassword.setBackground(getDrawable(R.drawable.text_border_error));
                */
                return;
            }
        }
        AuthenticationDetails authenticationDetails = new AuthenticationDetails(this.username, password, null);
        continuation.setAuthenticationDetails(authenticationDetails);
        continuation.continueTask();
    }

    // initialize app
    private void initApp() {
        inUsername = (EditText) findViewById(R.id.txtId);
        inPassword = (EditText) findViewById(R.id.txtPassword);
    }


    // Callbacks
    ForgotPasswordHandler forgotPasswordHandler = new ForgotPasswordHandler() {
        @Override
        public void onSuccess() {
            DismissConnectDialog(); //closeWaitDialog();
            showNotiMsg(LoginActivity.this,"비밀번호를 변경하였습니다.");
            //showDialogMessage("Password successfully changed!","");
            inPassword.setText("");
            inPassword.requestFocus();
        }

        @Override
        public void getResetCode(ForgotPasswordContinuation forgotPasswordContinuation) {
            DismissConnectDialog(); //closeWaitDialog();
            getForgotPasswordCode(forgotPasswordContinuation);
        }

        @Override
        public void onFailure(Exception e) {
            DismissConnectDialog(); //closeWaitDialog();
            showNotiMsg(LoginActivity.this,"비밀번호를 변경하지 못하였습니다.");
            //showDialogMessage("Forgot password failed",AppHelper.formatException(e));
        }
    };

    //
    AuthenticationHandler authenticationHandler = new AuthenticationHandler() {
        @Override
        public void onSuccess(CognitoUserSession cognitoUserSession, CognitoDevice device) {
            DebugLogOutput(TAG, " -- Auth Success");
            SharedPrefUtil.putLong(LOGIN_TIME, System.currentTimeMillis());
            AppHelper.setCurrSession(cognitoUserSession);
            AppHelper.newDevice(device);
            DismissConnectDialog(); //closeWaitDialog();
            launchUser();
        }

        @Override
        public void getAuthenticationDetails(AuthenticationContinuation authenticationContinuation, String username) {
            DismissConnectDialog(); //closeWaitDialog();
            Locale.setDefault(Locale.US);
            getUserAuthentication(authenticationContinuation, username);
        }

        @Override
        public void getMFACode(MultiFactorAuthenticationContinuation multiFactorAuthenticationContinuation) {
            DismissConnectDialog(); //closeWaitDialog();
            mfaAuth(multiFactorAuthenticationContinuation);
        }

        @Override
        public void onFailure(Exception e) {
            DismissConnectDialog(); //closeWaitDialog();
            showNotiMsg(LoginActivity.this,"로그인에 실패하였습니다.");
            //Toast.makeText(LoginActivity.this,"Sign-in failed",Toast.LENGTH_SHORT).show();
            /*
            TextView label = (TextView) findViewById(R.id.textViewUserIdMessage);
            label.setText("Sign-in failed");
            inPassword.setBackground(getDrawable(R.drawable.text_border_error));

            label = (TextView) findViewById(R.id.textViewUserIdMessage);
            label.setText("Sign-in failed");
            inUsername.setBackground(getDrawable(R.drawable.text_border_error));
            */
            //showDialogMessage("Sign-in failed", AppHelper.formatException(e));
        }

        @Override
        public void authenticationChallenge(ChallengeContinuation continuation) {
            /**
             * For Custom authentication challenge, implement your logic to present challenge to the
             * user and pass the user's responses to the continuation.
             */
            if ("NEW_PASSWORD_REQUIRED".equals(continuation.getChallengeName())) {
                // This is the first sign-in attempt for an admin created user
                newPasswordContinuation = (NewPasswordContinuation) continuation;
                AppHelper.setUserAttributeForDisplayFirstLogIn(newPasswordContinuation.getCurrentUserAttributes(),
                        newPasswordContinuation.getRequiredAttributes());
                DismissConnectDialog(); //closeWaitDialog();
                firstTimeSignIn();
            } else if ("SELECT_MFA_TYPE".equals(continuation.getChallengeName())) {
                DismissConnectDialog(); //closeWaitDialog();
                mfaOptionsContinuation = (ChooseMfaContinuation) continuation;
                List<String> mfaOptions = mfaOptionsContinuation.getMfaOptions();
                selectMfaToSignIn(mfaOptions, continuation.getParameters());
            }
        }
    };

    private void clearInput() {
        inUsername.setText("");
        inUsername.requestFocus();
        inPassword.setText("");
    }

    private void showWaitDialog(String message) {
        closeWaitDialog();
        waitDialog = new ProgressDialog(this);
        waitDialog.setTitle(message);
        waitDialog.show();
    }

    private void showDialogMessage(String title, String body) {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(title).setMessage(body).setNeutralButton("OK", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                try {
                    userDialog.dismiss();
                } catch (Exception e) {
                    //
                }
            }
        });
        userDialog = builder.create();
        userDialog.show();
    }

    private void closeWaitDialog() {
        try {
            waitDialog.dismiss();
        }
        catch (Exception e) {
            //
        }
    }


    //GOOGLE AUTH
    /**
     * Validates that there is a reasonable server client ID in strings.xml, this is only needed
     * to make sure users of this sample follow the README.
     */
    private void validateServerClientID() {
        String serverClientId = getString(R.string.google_auth_server_client_id);
        String suffix = ".apps.googleusercontent.com";
        if (!serverClientId.trim().endsWith(suffix)) {
            String message = "Invalid server client ID in strings.xml, must end with " + suffix;

            Log.w(TAG, message);
            Toast.makeText(this, message, Toast.LENGTH_LONG).show();
        }
    }

    private void getAuthCode() {
        // Start the retrieval process for a server auth code.  If requested, ask for a refresh
        // token.  Otherwise, only get an access token if a refresh token has been previously
        // retrieved.  Getting a new access token for an existing grant does not require
        // user consent.
        Intent signInIntent = mGoogleSignInClient.getSignInIntent();
        startActivityForResult(signInIntent, RESULT_GOOGE_GET_AUTH_CODE);
    }

    private void signOut() {
        mGoogleSignInClient.signOut().addOnCompleteListener(this, new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                updateUI(null);
            }
        });
    }

    private void revokeAccess() {
        mGoogleSignInClient.revokeAccess().addOnCompleteListener(this,
                new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {
                        updateUI(null);
                    }
                });
    }

    private void updateUI(@Nullable GoogleSignInAccount account) {
        if (account != null) {
            String authCode = account.getServerAuthCode();
            ErrorLogOutput(TAG,"Auth Code : " + authCode + "\nEmail : "+ account.getEmail() + "\nGivenName : "+ account.getGivenName() + "\nID : "+ account.getId());

        } else {
            ErrorLogOutput(TAG,"Auth Code : null");
        }
    }
}