package co.pixelbeard.theanfieldwrap.signUp;

import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.fragment.app.FragmentManager;

import com.dpizarro.uipicker.library.picker.PickerUI;
import com.dpizarro.uipicker.library.picker.PickerUISettings;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Locale;

import br.com.simplepass.loadingbutton.customViews.CircularProgressButton;
import butterknife.BindView;
import butterknife.ButterKnife;
import co.pixelbeard.theanfieldwrap.R;
import co.pixelbeard.theanfieldwrap.data.source.DataRepository;
import co.pixelbeard.theanfieldwrap.data.source.local.LocalRepository;
import co.pixelbeard.theanfieldwrap.data.source.remote.RemoteRepository;
import co.pixelbeard.theanfieldwrap.home.HomeActivity;
import co.pixelbeard.theanfieldwrap.login.LoginActivity;
import co.pixelbeard.theanfieldwrap.signUp.auth.SignUpAuthCodeFragment;
import co.pixelbeard.theanfieldwrap.signUp.emailPassword.SignUpEmailPasswordFragment;
import co.pixelbeard.theanfieldwrap.signUp.name.SignUpNameFragment;
import co.pixelbeard.theanfieldwrap.utils.ActivityExtraTags;
import co.pixelbeard.theanfieldwrap.utils.AnimUtils;
import co.pixelbeard.theanfieldwrap.utils.BaseActivity;
import co.pixelbeard.theanfieldwrap.utils.ConnectionUtils;
import co.pixelbeard.theanfieldwrap.utils.DialogUtils;
import co.pixelbeard.theanfieldwrap.utils.FontUtils;
import co.pixelbeard.theanfieldwrap.utils.FragmentUtils;
import co.pixelbeard.theanfieldwrap.walkthrough.WalkthroughActivity;
import io.realm.Realm;

public class SignUpActivity extends BaseActivity implements SignUpContract.View, SignUpFragmentListener {

    @BindView(R.id.ll_back)
    LinearLayout llBack;
    @BindView(R.id.btn_next)
    CircularProgressButton btnNext;
    @BindView(R.id.txt_registration_step)
    TextView txtRegStep;
    @BindView(R.id.fl_frag_container)
    FrameLayout flFragContainer;
    @BindView(R.id.btn_resend_code)
    Button btnResendCode;

    @BindView(R.id.ll_no_internet_header)
    LinearLayout llNoInternetHeader;
    @BindView(R.id.txt_no_internet_header)
    TextView txtNoInternetHeader;
    @BindView(R.id.countries_picker)
    PickerUI countriesPicker;

    private String mFirstName, mLastName, mUserName, mEmail, mPassword, mCountry;

    private FragmentManager mFragMan;

    private SignUpContract.Presenter mPresenter;

    private boolean fromLogin;

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

        ButterKnife.bind(this);

        new SignUpPresenter(this, new DataRepository(new LocalRepository(Realm.getDefaultInstance()), new RemoteRepository()));
        fromLogin = getIntent().getBooleanExtra(ActivityExtraTags.BOOL_FROM_LOGIN, false);

        setupFragmentManager();

        setButtonFont();
        setButtonClickListener();

        setTextViewFont();

        if (fromLogin) {
            mEmail = getIntent().getStringExtra(ActivityExtraTags.STRING_USER_EMAIL);
            setSignUpAuthCodeFrag();
        } else {
            setSignUpNameFrag();
        }

        txtNoInternetHeader.setText(getString(R.string.no_internet_connection));
    }

    private void setupFragmentManager() {
        mFragMan = getSupportFragmentManager();
        mFragMan.addOnBackStackChangedListener(() -> {
            if (mFragMan.getBackStackEntryCount() > 0) {
                String tag = mFragMan.getBackStackEntryAt(mFragMan.getBackStackEntryCount() - 1).getName();
                if (tag != null) {
                    switch (tag) {
                        case "SIGN_UP_NAME":
                            txtRegStep.setText(getString(R.string.sign_up_step_1));
                            btnResendCode.setVisibility(View.INVISIBLE);
                            break;
                        case "SIGN_UP_EMAIL":
                            txtRegStep.setText(getString(R.string.sign_up_step_2));
                            btnResendCode.setVisibility(View.INVISIBLE);
                            break;
                        case "SIGN_UP_AUTH":
                            txtRegStep.setText(getString(R.string.sign_up_step_3));
                            btnResendCode.setVisibility(View.VISIBLE);
                            break;
                    }
                }
            }
        });
    }

    private void setButtonFont() {
        btnNext.setTypeface(FontUtils.getInstance().getDinAlternateBold());
        btnResendCode.setTypeface(FontUtils.getInstance().getDinCondensedBold());
    }

    private void setButtonClickListener() {

        llBack.setOnClickListener(v -> mPresenter.backClicked());

        btnNext.setOnClickListener(v -> mPresenter.nextClicked(mFragMan));

        btnResendCode.setOnClickListener(v -> {
            mPresenter.resendActivationCode(mEmail);
        });
    }

    private void setTextViewFont() {
        txtRegStep.setTypeface(FontUtils.getInstance().getDinCondensedBold());
        txtNoInternetHeader.setTypeface(FontUtils.getInstance().getDinAlternateBold());
    }

    @Override
    public void setSignUpNameFrag() {
        FragmentUtils.doReplaceFragmentTransaction(mFragMan, flFragContainer.getId(), SignUpNameFragment.newInstance(), "SIGN_UP_NAME", true);
    }

    @Override
    public void setSignUpEmailPasswordFrag() {
        FragmentUtils.doReplaceFragmentTransaction(mFragMan, flFragContainer.getId(), SignUpEmailPasswordFragment.newInstance(), "SIGN_UP_EMAIL", true);
    }

    @Override
    public void setSignUpAuthCodeFrag() {
        if (!isFinishing()) {
            FragmentUtils.clearBackStack(mFragMan);
            FragmentUtils.doReplaceFragmentTransaction(mFragMan, flFragContainer.getId(), SignUpAuthCodeFragment.newInstance(mEmail, mPassword, fromLogin), "SIGN_UP_AUTH", true);
        }
    }

    @Override
    public void showCodeResentToast() {
        Toast.makeText(this, getString(R.string.auth_code_sent), Toast.LENGTH_LONG).show();
    }

    @Override
    public void showErrorSendingCodeToast() {
        Toast.makeText(this, getString(R.string.auth_code_error), Toast.LENGTH_LONG).show();
    }

    @Override
    public void showNoConnectionHeader() {
        showNoInternetHeader();
    }

    @Override
    public void showSingleButtonDialog(String title, String body, DialogInterface.OnDismissListener listener) {

        DialogUtils.showSingleButtonDialog(title, body, this, listener);
    }


    @Override
    public void startHomeActivity() {
        Intent intent = new Intent(this, HomeActivity.class);
        startActivity(intent);
        finish();
        overridePendingTransition(R.anim.slide_in_from_right, R.anim.slide_out_left);

    }

    @Override
    public void startLoginActivity() {
        Intent intent = new Intent(this, LoginActivity.class);
        startActivity(intent);
        finish();
        overridePendingTransition(R.anim.slide_in_from_right, R.anim.slide_out_left);
    }

    private void startWalkthroughActivity() {
        Intent intent = new Intent(this, WalkthroughActivity.class);
        startActivity(intent);
        finish();
        overridePendingTransition(R.anim.slide_in_from_left_fast, R.anim.slide_out_right);

    }

    @Override
    public void setFirstName(String firstName) {
        this.mFirstName = firstName;
    }

    @Override
    public void setLastName(String lastName) {
        this.mLastName = lastName;
    }

    @Override
    public void setUserName(String userName) {
        this.mUserName = userName;
    }

    @Override
    public void setEmail(String email) {
        this.mEmail = email;
    }

    @Override
    public void setPassword(String password) {
        this.mPassword = password;
    }

    @Override
    public void setCountry(String country) {
        this.mCountry = country;
    }

    @Override
    public void enableButton() {
        btnNext.setAlpha(1.0f);
    }

    @Override
    public void disableButton() {
        btnNext.setAlpha(0.2f);
    }

    @Override
    public void registerUser() {
        mPresenter.registerUser(mFirstName, mLastName, mEmail, mPassword, mCountry, true, mUserName);
    }

    @Override
    public void convertGuestToFull() {
        mPresenter.convertGuestToFullUser(mFirstName, mLastName, mEmail, mPassword, mCountry, true, mUserName);
    }

    @Override
    public void onBackPressed() {
        if (mFragMan.getBackStackEntryCount() > 1) {
            mFragMan.popBackStack();
        } else if (isFromGuest()) {
            finish();
        } else {
            startWalkthroughActivity();
        }
    }

    @Override
    public void setPresenter(SignUpContract.Presenter presenter) {
        if (presenter != null) {
            this.mPresenter = presenter;
        } else {
            throw new RuntimeException("Presenter is null");
        }
    }

    @Override
    public void goBack() {
        onBackPressed();
    }

    @Override
    public void showLoader(String text) {
        if (!isFinishing()) {
            btnNext.startMorphAnimation();
        }
    }

    @Override
    public void hideLoader() {
        if (!isFinishing()) {
            btnNext.revertAnimation(() -> null);
        }
    }

    @Override
    public void onUnknownError(String error) {
        if (!isFinishing()) {
            showSingleButtonDialog(getString(R.string.error), error, null);
        }
    }

    @Override
    public void onTimeout() {
        if (!isFinishing()) {
            showSingleButtonDialog(getString(R.string.timeout_title), getString(R.string.timeout_body), null);
        }
    }

    @Override
    public void onNetworkError() {
        if (!isFinishing()) {
            showSingleButtonDialog(getString(R.string.network_error_title), getString(R.string.network_error_body), null);
        }
    }


    @Override
    public void onConnectionError() {
        if (!isFinishing()) {
            showNoInternetHeader();
        }
    }

    @Override
    public void logoutUser() {
        //Not needed
    }

    @Override
    public boolean checkConnection() {
        return ConnectionUtils.userHasConnection(this);
    }

    @Override
    public boolean isFromGuest() {
        return getIntent().getBooleanExtra(ActivityExtraTags.BOOL_FROM_GUEST, false);
    }

    @Override
    public void finishSignUpActivity() {
        finish();
    }

    @Override
    public void showNoInternetHeader() {
        AnimUtils.slideInTop(llNoInternetHeader, 300, new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                llNoInternetHeader.setVisibility(View.VISIBLE);
                hideNoInternetHeader();
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        }, new AccelerateInterpolator());
    }

    public void hideNoInternetHeader() {
        new Handler().postDelayed(() -> {
            AnimUtils.slideOutTop(llNoInternetHeader, 300, new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {
                    llNoInternetHeader.setVisibility(View.INVISIBLE);
                }

                @Override
                public void onAnimationEnd(Animation animation) {

                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }
            });
        }, 3000);
    }

    @Override
    public void showCountriesPicker(PickerUI.PickerUIItemClickListener listener) {

        Locale[] locales = Locale.getAvailableLocales();
        ArrayList<String> countries = new ArrayList<>();

        int defaultLocalePos = -1;
        Locale defaultLocale = Locale.getDefault();

        for (int i = 0; i < locales.length; i++) {
            Locale locale = locales[i];
            String country = locale.getDisplayCountry();

            if (country.trim().length() > 0 && !countries.contains(country)) {
                countries.add(country);

            }
        }

        Collections.sort(countries);
        for (String country : countries) {
            if (defaultLocale.getDisplayCountry().equals(country)) {
                defaultLocalePos = countries.indexOf(country);
            }
        }


        PickerUISettings pickerUISettings = new PickerUISettings.Builder()
                .withItems(countries)
                .withAutoDismiss(false)
                .withItemsClickables(false)
                .build();

        countriesPicker.setSettings(pickerUISettings);


        countriesPicker.setOnClickItemPickerUIListener(listener);


        if (defaultLocalePos != -1) {
            countriesPicker.slide(defaultLocalePos);
            int finalDefaultLocalePos = defaultLocalePos;
            new Handler().postDelayed(() -> listener.onItemClickPickerUI(0, finalDefaultLocalePos, defaultLocale.getDisplayCountry()), 200);
        } else {
            countriesPicker.slide();
        }

    }
}
