package de.beyondsoft.ownchat.page.login;

import com.google.firebase.iid.FirebaseInstanceId;

import de.beyondsoft.ownchat.BewoplanerApplication;
import de.beyondsoft.ownchat.R;
import de.beyondsoft.ownchat.data.AppPrefsConstants;
import de.beyondsoft.ownchat.data.prefs.AppPrefs;
import de.beyondsoft.ownchat.data.prefs.BooleanPreference;
import de.beyondsoft.ownchat.di.InjectionHelper;
import de.beyondsoft.ownchat.page.main.MainActivity;
import de.beyondsoft.ownchat.utils.AppStoppedService;
import de.beyondsoft.ownchat.utils.DialogHandler;
import de.beyondsoft.ownchat.utils.ui.ViewUtils;
import com.securepreferences.SecurePreferences;

import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.Toast;

import java.util.Map;

import javax.inject.Inject;
import javax.inject.Named;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnEditorAction;

/**
 * Created by imarneanu on 2/10/17.
 */
public class LoginActivity extends AppCompatActivity implements LoginView {

    @BindView(R.id.login_chat_code)
    EditText mChatCodeEditText;
    @BindView(R.id.login_account)
    EditText mAccountEditText;
    @BindView(R.id.login_username)
    EditText mUsernameEditText;
    @BindView(R.id.login_password)
    EditText mPasswordEditText;
    @BindView(R.id.login_button)
    Button mLoginButton;
    @BindView(R.id.login_progress_bar)
    ProgressBar mProgressBar;
    @BindView(R.id.login_save_password_checkBox)
    CheckBox mSavePasswordCheckbox;

    @Inject
    @Named(AppPrefsConstants.SHOW_LOGIN_AGAIN)
    BooleanPreference mShowLoginAgainPreference;

    @Inject
    LoginPresenter mLoginPresenter;

    @Inject
    @AppPrefs
    SecurePreferences mSecuredPrefs;

    private Snackbar mSnackbar;
    private Callback mCallback;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        InjectionHelper.getLoginComponent(this).inject(this);
        ButterKnife.bind(this);
        mLoginPresenter.attachView(this);
        decryptPreference();
        ViewUtils.setProgressBarColor(mProgressBar, R.color.colorDefault);

        if(mShowLoginAgainPreference.get()) {
            mShowLoginAgainPreference.set(false);
            showError(R.string.login_again);
        }

        mCallback.logout(Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID), false, null);
    }

    @OnEditorAction(R.id.login_password)
    public boolean passwordDoneClicked(int actionId) {
        if (actionId == EditorInfo.IME_ACTION_DONE) {
            ViewUtils.hideKeyboard(this);
        }

        return false;
    }

    @OnClick(R.id.login_button)
    void loginButtonClicked() {
        mCallback.checkTypeAndCustomerId(mAccountEditText.getText().toString().trim(), mPasswordEditText.getText().toString().trim(), mSavePasswordCheckbox.isChecked());
    }

    @Override
    public void customerIdIsValid() {
        ((BewoplanerApplication) getApplication()).resetApplicationComponent();
        verifyIfIsChecked();
    }

    @Override
    public void customerIdIsNotValid(int status) {
        int dialogMessage;

        switch (status) {
            case 1:
                dialogMessage = R.string.login_customer_id_is_invalid;
                break;
            default:
                dialogMessage = R.string.login_service_type_is_undefined;
        }

        DialogHandler.createNoTitleDialog(this,
                dialogMessage,
                false,
                android.R.string.ok,
                (dialog, which) -> dialog.dismiss()).show();
    }

    private void verifyIfIsChecked() {
        mLoginPresenter.detachView();
        InjectionHelper.destroyLoginComponent();
        InjectionHelper.getLoginComponent(this).inject(this);
        mLoginPresenter.attachView(this);

        mCallback.tryToLogin(mUsernameEditText.getText().toString().trim(), mPasswordEditText.getText().toString(), mChatCodeEditText.getText().toString().trim());
    }

    @Override
    public void loginSuccessful() {
        mCallback.retrieveUploadMaxSize();
    }

    @Override
    public void retrievedUploadMaxSize() {
        mCallback.tryToRegisterDevice(Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID), FirebaseInstanceId.getInstance().getToken());

        if (!mSavePasswordCheckbox.isChecked()) {
            startService(new Intent(getBaseContext(), AppStoppedService.class));
        }

        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        finish();
    }

    //TODO: change defaultValue: null to defaultValue: ""
    private void decryptPreference() {
        for (Map.Entry<String, ?> entry : mSecuredPrefs.getAll().entrySet()) {
            final String key = entry.getKey();

            if (key == null) {
                continue;
            } else if (key.equals(SecurePreferences.hashPrefKey(AppPrefsConstants.CHAT_CODE))) {
                mChatCodeEditText.setText(String.valueOf(mSecuredPrefs.getString(AppPrefsConstants.CHAT_CODE, null)));
            } else if (key.equals(SecurePreferences.hashPrefKey(AppPrefsConstants.ACCOUNT_NO))) {
                mAccountEditText.setText(String.valueOf(mSecuredPrefs.getString(AppPrefsConstants.ACCOUNT_NO, null)));
            } else if(key.equals(SecurePreferences.hashPrefKey(AppPrefsConstants.USER_NAME))) {
                mUsernameEditText.setText(String.valueOf(mSecuredPrefs.getString(AppPrefsConstants.USER_NAME, null)));
            } else if(key.equals(SecurePreferences.hashPrefKey(AppPrefsConstants.USER_PASSWORD))) {
                mPasswordEditText.setText(String.valueOf(mSecuredPrefs.getString(AppPrefsConstants.USER_PASSWORD, null)));
            } else if(key.equals(SecurePreferences.hashPrefKey(AppPrefsConstants.SAVE_PASSWORD))) {
                mSavePasswordCheckbox.setChecked(mSecuredPrefs.getBoolean(AppPrefsConstants.SAVE_PASSWORD, false));
            }
        }
    }

    @Override
    public void setCallback(Callback callback) {
        mCallback = callback;
    }

    @Override
    public void showLoading() {
        mSavePasswordCheckbox.setEnabled(false);
        mUsernameEditText.setEnabled(false);
        mPasswordEditText.setEnabled(false);
        mChatCodeEditText.setEnabled(false);
        mAccountEditText.setEnabled(false);
        mProgressBar.setVisibility(View.VISIBLE);
        mLoginButton.setVisibility(View.GONE);
    }

    @Override
    public void showContent() {
        mSavePasswordCheckbox.setEnabled(true);
        mUsernameEditText.setEnabled(true);
        mPasswordEditText.setEnabled(true);
        mChatCodeEditText.setEnabled(true);
        mAccountEditText.setEnabled(true);
        mProgressBar.setVisibility(View.GONE);
        mLoginButton.setVisibility(View.VISIBLE);
    }

    @Override
    public void showError(@StringRes int messageRes) {
        showError(getString(messageRes));
    }

    @Override
    public void showError(String message) {
        if (mSnackbar == null) {
            mSnackbar = Snackbar.make(findViewById(R.id.login_coordinator_layout), message, Snackbar.LENGTH_LONG).setAction("Retry", view -> verifyIfIsChecked());
            mSnackbar.setActionTextColor(ContextCompat.getColor(this, R.color.colorDefault));
        }

        mSnackbar.setText(message);
        mSnackbar.show();
    }

    @Override
    protected void onDestroy() {
        InjectionHelper.destroyLoginComponent();
        mLoginPresenter.detachView();
        super.onDestroy();
    }
}
