package com.getbubblenow.android.activity;

import androidx.appcompat.widget.AppCompatButton;
import androidx.lifecycle.ViewModelProvider;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable;

import android.content.Intent;
import android.os.Bundle;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.getbubblenow.android.R;
import com.getbubblenow.android.api.enums.MFAuthType;
import com.getbubblenow.android.viewmodel.MFAVerifyViewModel;
import com.jakewharton.rxbinding4.view.RxView;
import com.jakewharton.rxbinding4.widget.RxTextView;


public class MFAVerifyActivity extends BaseActivityBubble {

    private static final int MFA_TOKEN_LENGTH = 6;
    private static final String AUTH_TYPE_KEY = "authType";

    private final CompositeDisposable compositeSubscription = new CompositeDisposable();
    private MFAVerifyViewModel mfaVerifyViewModel;
    private EditText verification;
    private AppCompatButton verifyButton;
    private TextView backToSignInButton;
    private ImageView authLogo;

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

        mfaVerifyViewModel = new ViewModelProvider(this).get(MFAVerifyViewModel.class);
        mfaVerifyViewModel.setAuthType((MFAuthType) getIntent().getSerializableExtra(AUTH_TYPE_KEY));

        initUI();
    }

    @Override protected void onDestroy() {
        super.onDestroy();
        compositeSubscription.dispose();
    }

    private void initUI() {
        initViews();
        initBindings();
    }

    private void initViews() {
        verification = findViewById(R.id.verification);
        verifyButton = findViewById(R.id.verifyButton);
        backToSignInButton = findViewById(R.id.backToSignInButton);
        authLogo = findViewById(R.id.auth_logo);
        setAuthLogo(mfaVerifyViewModel.getAuthType());
    }

    private void initBindings() {

        final @NonNull Disposable verifySubscription = RxView.clicks(verifyButton)
                .subscribe(aVoid -> loginWithAuth());
        compositeSubscription.add(verifySubscription);

        final @NonNull Disposable backToSignInSubscription = RxView.clicks(backToSignInButton)
                .subscribe(aVoid -> backToSignIn());
        compositeSubscription.add(backToSignInSubscription);

        final @NonNull Disposable verificationTextChange = RxTextView.afterTextChangeEvents(verification)
                .subscribe(textViewAfterTextChangeEvent -> setVerifyButtonState(textViewAfterTextChangeEvent.getEditable()));
        compositeSubscription.add(verificationTextChange);

        verification.setOnEditorActionListener((view, actionId, event) -> {
            boolean handled = false;
            if (actionId == EditorInfo.IME_ACTION_SEND && checkVerificationCode(view.getText())) {
                loginWithAuth();
                handled = true;
            } else {
                view.setError(getString(R.string.invalid_mfa_token_format));
            }
            return handled;
        });
    }

    private void loginWithAuth() {
        final String mfaToken = verification.getText().toString();
        showLoadingDialog();
        mfaVerifyViewModel.loginWithAuth(this, mfaToken)
                .observe(this, statusResource -> {
                    switch (statusResource.status) {
                        case SUCCESS:
                            closeLoadingDialog();
                            final Intent mainActivityIntent = new Intent(this, MainActivity.class);
                            mainActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
                            startActivity(mainActivityIntent);
                            break;
                        case LOADING:
                        case EMPTY:
                            break;
                        case AUTH:
                            closeLoadingDialog();
                            setAuthLogo(statusResource.authType);
                            break;
                        case ERROR:
                            closeLoadingDialog();
                            Toast.makeText(this, statusResource.message, Toast.LENGTH_SHORT).show();
                            break;
                    }
                });
    }

    private void setAuthLogo(final MFAuthType authType) {
        switch (authType) {
            case TOTP:
                authLogo.setImageDrawable(getTheme().getDrawable(R.drawable.authenticator));
                break;
            case EMAIL:
                authLogo.setImageDrawable(getTheme().getDrawable(R.drawable.email));
                break;
            case SMS:
                authLogo.setImageDrawable(getTheme().getDrawable(R.drawable.sms));
                break;
            case NONE:
                break;
        }
    }

    private void backToSignIn() {
        final Intent intent = new Intent(this, LoginActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        startActivity(intent);
    }

    private void setVerifyButtonState(final CharSequence text) {
        if (checkVerificationCode(text)) {
            verifyButton.setBackgroundDrawable(getDrawable(R.drawable.sign_in_enable));
            verifyButton.setEnabled(true);
        } else {
            verifyButton.setBackgroundDrawable(getDrawable(R.drawable.sign_in_disable));
            verifyButton.setEnabled(false);
        }
    }

    private static boolean checkVerificationCode(final CharSequence text) {
        return text.length() == MFA_TOKEN_LENGTH;
    }
}
