package com.getbubblenow.android.activity;

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

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.getbubblenow.android.R;
import com.getbubblenow.android.api.ApiConstants;
import com.getbubblenow.android.repository.CredentialRepository;
import com.getbubblenow.android.viewmodel.LoginViewModel;
import com.jakewharton.rxbinding4.widget.RxTextView;


public class LoginActivity extends BaseActivityBubble {

    private static final String USER_NAME_KEY = "userName";
    private static final String PASSWORD_KEY = "password";
    private static final String NO_INTERNET_CONNECTION = "no internet connection";
    private static final String LOGIN_FAILED = "Login Failed";
    private static final String REGISTER_POSTFIX = "/register";
    private static final String RESOURCE_KEY = "resource";

    private LoginViewModel loginViewModel;
    private EditText userName;
    private EditText password;
    private AppCompatButton sign;
    private TextView signUpButton;
    private TextView setLauncherButton;

    private String resource;
    private boolean userNameStateFlag;
    private boolean passwordStateFlag;

    private final CompositeDisposable compositeSubscription = new CompositeDisposable();

    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        resource = getIntent().getStringExtra(RESOURCE_KEY);
        setContentView(R.layout.activity_login);
        initUI();
        loginViewModel = new ViewModelProvider(this).get(LoginViewModel.class);
    }

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

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

    private void initListeners() {
        sign.setOnClickListener(v -> signIn());
        userNameStateListener();
        passwordStateListener();
        sendListener();
        signUpButton.setOnClickListener(v -> signUp());
        setLauncherButton.setOnClickListener(v -> setLauncher());
    }

    private void setLauncher() {
        final Intent intent = new Intent(this, SetLauncherActivity.class);
        startActivity(intent);
    }

    private void signUp() {
        showLoadingDialog();
        LoginViewModel.getSignUpSage(this).observe(this, statusResource -> {
            switch (statusResource.status) {
                case SUCCESS:
                    closeLoadingDialog();
                    final String sage = statusResource.data;
                    final String url = sage + REGISTER_POSTFIX;
                    final Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setData(Uri.parse(url));
                    startActivity(intent);
                    break;
                case ERROR:
                    closeLoadingDialog();
                    showErrorDialog(statusResource.message);
                    break;
                case LOADING:
                case EMPTY:
                case AUTH:
                    break;
            }
        });
    }

    private void initViews() {
        userName = findViewById(R.id.userName);
        if (resource != null && !resource.isEmpty()) {
            userName.setText(resource);
            userName.setEnabled(false);
        } else {
            userName.setEnabled(true);
        }
        password = findViewById(R.id.password);
        sign = findViewById(R.id.signButton);
        signUpButton = findViewById(R.id.signUpButton);
        setLauncherButton = findViewById(R.id.setLauncherButton);
    }


    private void sendListener() {
        password.setOnEditorActionListener((v, actionId, event) -> {
            if ((event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP)
                    || (actionId == EditorInfo.IME_ACTION_SEND)) {
                if (!TextUtils.isEmpty(password.getText().toString()) && !TextUtils.isEmpty(userName.getText().toString())) {
                    signIn();
                } else {
                    Toast.makeText(this, getString(R.string.empty_message), Toast.LENGTH_SHORT).show();
                }
                return true;
            }
            return false;
        });
    }

    private void userNameStateListener() {
        final Disposable subscribe = RxTextView
                .afterTextChangeEvents(userName)
                .subscribe(view -> {
                    userNameStateFlag = !userName.getText().toString().trim().isEmpty();
                    setButtonState();
                });
        compositeSubscription.add(subscribe);
    }

    private void passwordStateListener() {
        final Disposable subscribe = RxTextView
                .afterTextChangeEvents(password)
                .subscribe(view -> {
                    passwordStateFlag = !password.getText().toString().trim().isEmpty();
                    setButtonState();
                });
        compositeSubscription.add(subscribe);
    }

    private void signIn() {
        final String usernameInput = userName.getText().toString().trim();
        final String passwordInput = password.getText().toString().trim();

        if (!LoginViewModel.getHostNameForAccount(this).isEmpty()) {
            CredentialRepository.getInstance(getApplicationContext()).setNodePassword(passwordInput);
            final Intent mainActivityIntent = new Intent(this, MainActivity.class);
            mainActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            startActivity(mainActivityIntent);
            return;
        }

        if (loginViewModel.checkRepositoryInstance()) {
            loginViewModel.buildRepositoryInstance(this, ApiConstants.BOOTSTRAP_URL);
        } else {
            loginViewModel.buildClientService(ApiConstants.BOOTSTRAP_URL);
        }

        showLoadingDialog();
        LoginViewModel.loginToSage(this, usernameInput, passwordInput)
                .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();
                            final Intent mfaVerifyActivityIntent = new Intent(this, MFAVerifyActivity.class);
                            mfaVerifyActivityIntent.putExtra("authType", statusResource.authType);
                            startActivity(mfaVerifyActivityIntent);
                            break;
                        case ERROR:
                            closeLoadingDialog();

                            if (statusResource.message == null) {
                                throw new IllegalStateException("Message in the status cannot be null");
                            }

                            if (statusResource.message.equals(NO_INTERNET_CONNECTION)) {
                                showNetworkNotAvailableMessage();
                            } else if (statusResource.message.equals(LOGIN_FAILED)) {
                                Toast.makeText(this, getString(R.string.login_failed), Toast.LENGTH_LONG).show();
                            } else {
                                showErrorDialog(statusResource.message);
                            }
                            break;
                    }
                });
    }

    private void setButtonState(){
        if(userNameStateFlag  && passwordStateFlag){
            sign.setBackgroundDrawable(getDrawable(R.drawable.sign_in_enable));
            sign.setEnabled(true);
        }
        else {
            sign.setBackgroundDrawable(getDrawable(R.drawable.sign_in_disable));
            sign.setEnabled(false);
        }
    }

    @Override protected void onSaveInstanceState(@NonNull final Bundle outState) {
        outState.putBoolean(USER_NAME_KEY,userNameStateFlag);
        outState.putBoolean(PASSWORD_KEY,passwordStateFlag);
        super.onSaveInstanceState(outState);
    }

    @Override protected void onRestoreInstanceState(@NonNull final Bundle savedInstanceState) {
        userNameStateFlag = savedInstanceState.getBoolean(USER_NAME_KEY);
        passwordStateFlag = savedInstanceState.getBoolean(PASSWORD_KEY);
        super.onRestoreInstanceState(savedInstanceState);
    }
}
