package de.beyondsoft.ownchat.page.main;

import de.beyondsoft.ownchat.R;
import de.beyondsoft.ownchat.data.AppPrefsConstants;
import de.beyondsoft.ownchat.data.events.InvalidTokenEvent;
import de.beyondsoft.ownchat.data.events.LogoutDirectlyEvent;
import de.beyondsoft.ownchat.data.prefs.BooleanPreference;
import de.beyondsoft.ownchat.data.prefs.StringPreference;
import de.beyondsoft.ownchat.di.InjectionHelper;
import de.beyondsoft.ownchat.page.chat.GroupChatActivity;
import de.beyondsoft.ownchat.page.chat.SingleChatActivity;
import de.beyondsoft.ownchat.page.contacts.ContactsFragment;
import de.beyondsoft.ownchat.page.impressum.ImpressumActivity;
import de.beyondsoft.ownchat.page.login.LoginActivity;
import de.beyondsoft.ownchat.page.login.LoginPresenter;
import de.beyondsoft.ownchat.page.profile.ProfileFragment;
import de.beyondsoft.ownchat.utils.Constants;
import de.beyondsoft.ownchat.utils.DialogHandler;/**/
import de.beyondsoft.ownchat.utils.SystemUtils;
import de.beyondsoft.ownchat.utils.Utils;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.NavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.Toast;

import java.util.Date;

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

import butterknife.BindView;
import butterknife.ButterKnife;
import de.beyondsoft.ownchat.utils.ui.GlideApp;
import de.hdodenhof.circleimageview.CircleImageView;

public class MainActivity extends AppCompatActivity implements MainNavigation, LogoutNavigation {

    private static final String REDIRECT_TO_CHAT = "redirect_to_chat";
    private static final String BUNDLE = "bundle";
    private static final String LOGOUT = "logout";

    @BindView(R.id.toolbar)
    Toolbar mToolbar;
    @BindView(R.id.drawer_layout)
    DrawerLayout mDrawer;
    @BindView(R.id.nav_view)
    NavigationView mNavigationView;
    @BindView(R.id.nav_listView)
    ListView mNavigationListView;

    @Inject
    LoginPresenter mLoginPresenter;

    @Inject
    @Named(AppPrefsConstants.AVATAR)
    StringPreference mAvatarPreference;

    @Inject
    @Named(AppPrefsConstants.LOGIN_TOKEN)
    StringPreference mLoginTokenPreference;

    @Inject
    @Named(AppPrefsConstants.CHAT_OPENED)
    BooleanPreference mChatOpenedPref;

    @Inject
    @Named(AppPrefsConstants.SAVE_PASSWORD)
    BooleanPreference mSavePassword;

    @Inject
    SystemUtils mSystemUtils;

    private boolean mLogoutClicked;
    private Date mBackButtonLastPressed;

    public static Intent createIntent(Context context, Bundle bundle, int numberOfUsers, int groupId) {
        Intent intent = new Intent(context, MainActivity.class);
        intent.putExtra(REDIRECT_TO_CHAT, true);
        intent.putExtra(BUNDLE, bundle);
        intent.putExtra(Constants.GROUP_ID, groupId);
        intent.putExtra(Constants.GROUP_NR_USERS, numberOfUsers);
        intent.putExtra(LOGOUT, false);
        return intent;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        InjectionHelper.getMainComponent(this).inject(this);
        EventBus.getDefault().register(this);
        setSupportActionBar(mToolbar);

        View headerLayout = mNavigationView.getHeaderView(0);
        CircleImageView avatar = headerLayout.findViewById(R.id.menu_profile_imageView);
        GlideApp.with(this)
                .load(mAvatarPreference.get())
                .into(avatar);

        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, mDrawer, mToolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
            @Override
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                GlideApp.with(MainActivity.this)
                        .load(mAvatarPreference.get())
                        .into(avatar);
                Utils.hideKeyboard(MainActivity.this);
            }
        };

        mDrawer.closeDrawer(GravityCompat.START);
        mDrawer.addDrawerListener(toggle);

        toggle.syncState();
        ArrayAdapter<String> adapter = new NavigationMenuAdapter(this, getResources().getStringArray(R.array.nav_menu), this);
        mNavigationListView.setAdapter(adapter);
        switchFragment(new ContactsFragment());
        onNewIntent(getIntent());
    }

    @SuppressLint("MissingSuperCall")
    @Override
    protected void onSaveInstanceState(Bundle outState) {
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

        if(intent.hasExtra(REDIRECT_TO_CHAT) && !mChatOpenedPref.get()) {
            Bundle message = intent.getBundleExtra(BUNDLE);
            Intent startIntent;

            if(intent.getIntExtra(Constants.GROUP_NR_USERS, 2) > 2) {
                startIntent = GroupChatActivity.createIntent(this, message);
            } else {
                startIntent = SingleChatActivity.createIntent(this, message);
            }

            mChatOpenedPref.set(true);

            startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
            startActivity(startIntent);
            intent.removeExtra(REDIRECT_TO_CHAT);
            setIntent(intent);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    private void switchFragment(@NonNull Fragment fragment) {
        switchFragment(fragment, true);
    }

    private void switchFragment(@NonNull Fragment fragment, boolean clearBackStack) {
        Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.content_main);

        if(fragment.getClass().isInstance(currentFragment)) {
            return;
        }

        if(clearBackStack) {
            Utils.clearFullBackStack(this);
        }

        addFragmentToBackStack(fragment);
    }

    private void addFragmentToBackStack(@NonNull Fragment fragment) {
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.content_main, fragment, fragment.getTag())
                .addToBackStack(fragment.getClass().getSimpleName())
                .commitAllowingStateLoss();
    }

    @Override
    public void onBackPressed() {
        if(!mSavePassword.get()) {
            Toast.makeText(this, getString(R.string.logout_by_back_button_confirmation), Toast.LENGTH_SHORT).show();

            Date kek = new Date();

            if(mBackButtonLastPressed != null && (kek.getTime() - mBackButtonLastPressed.getTime() < 2000L)) {
                return;
            }
        }

        mBackButtonLastPressed = new Date();

        if(mDrawer.isDrawerOpen(GravityCompat.START)) {
            mDrawer.closeDrawer(GravityCompat.START);
        }

        if(getSupportFragmentManager().getBackStackEntryCount() <= 1) {
            finish();
        }

        super.onBackPressed();
    }

    @Override
    public void goToContacts() {
        mDrawer.closeDrawer(GravityCompat.START);
        switchFragment(new ContactsFragment());
    }

    @Override
    public void goToProfile() {
        mDrawer.closeDrawer(GravityCompat.START);
        switchFragment(new ProfileFragment(), false);
    }

    @Override
    public void logout() {
        Dialog alertDialog = DialogHandler.createNoTitleDialog(this,
                R.string.logout_confirmation,
                false,
                android.R.string.yes,
                android.R.string.no,
                (dialog, which) -> {
                    mLogoutClicked = true;
                    mDrawer.closeDrawer(GravityCompat.START);
                    mLoginPresenter.logout(Settings.Secure.getString(MainActivity.this.getContentResolver(), Settings.Secure.ANDROID_ID), false, this);
                },
                (dialog, which) -> dialog.dismiss());

        if(!isFinishing()) {
            alertDialog.show();
        }
    }

    @Override
    public void goToImpressum() {
        mDrawer.closeDrawer(GravityCompat.START);
        Intent intent = new Intent(this, ImpressumActivity.class);
        startActivity(intent);
    }

    @Override
    public void logoutDirectly(boolean clearAllPrefs) {
        mLoginPresenter.logout(Settings.Secure.getString(MainActivity.this.getContentResolver(), Settings.Secure.ANDROID_ID), clearAllPrefs, this);
    }

    @Override
    public void goToLoginActivity() {
        if(isFinishing()) {
            return;
        }

        Intent intent = new Intent(MainActivity.this, LoginActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

        startActivity(intent);
        finish();
    }

    @SuppressWarnings("unused")
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onInvalidToken(InvalidTokenEvent invalidTokenEvent) {
        mLoginPresenter.verifyChatCode(this);
    }

    @SuppressWarnings("unused")
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onLogoutDirectlyEvent(LogoutDirectlyEvent logoutDirectlyEvent) {
        logoutDirectly(logoutDirectlyEvent.getClearAllPrefs());
    }

    @Override
    protected void onDestroy() {
        EventBus.getDefault().unregister(this);
        mChatOpenedPref.set(false);

        InjectionHelper.destroyMainComponents();
        super.onDestroy();
    }
}
