package com.p3.bewoplaner.page.main;

import com.bumptech.glide.Glide;
import com.p3.bewoplaner.R;
import com.p3.bewoplaner.data.AppPrefsConstants;
import com.p3.bewoplaner.data.events.InvalidTokenEvent;
import com.p3.bewoplaner.data.events.LogoutDirectlyEvent;
import com.p3.bewoplaner.data.prefs.BooleanPreference;
import com.p3.bewoplaner.data.prefs.StringPreference;
import com.p3.bewoplaner.di.InjectionHelper;
import com.p3.bewoplaner.page.chat.GroupChatActivity;
import com.p3.bewoplaner.page.chat.SingleChatActivity;
import com.p3.bewoplaner.page.contacts.ContactsFragment;
import com.p3.bewoplaner.page.impressum.ImpressumActivity;
import com.p3.bewoplaner.page.login.LoginActivity;
import com.p3.bewoplaner.page.login.LoginPresenter;
import com.p3.bewoplaner.page.profile.ProfileFragment;
import com.p3.bewoplaner.utils.Constants;
import com.p3.bewoplaner.utils.DialogHandler;
import com.p3.bewoplaner.utils.SystemUtils;
import com.p3.bewoplaner.utils.Utils;

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

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.ListView;
import android.widget.Toast;

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

import butterknife.BindView;
import butterknife.ButterKnife;
import de.hdodenhof.circleimageview.CircleImageView;

/**
 * Created by imarneanu on 2/9/17.
 */
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
    SystemUtils mSystemUtils;

    private boolean mLogoutClicked;

    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);
        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);
                Utils.hideKeyboard(MainActivity.this);
            }
        };
        mDrawer.closeDrawer(GravityCompat.START);
        mDrawer.addDrawerListener(toggle);
        View headerLayout = mNavigationView.getHeaderView(0);
        CircleImageView avatar = (CircleImageView) headerLayout.findViewById(R.id.menu_profile_imageView);
        Glide.with(this).load(mAvatarPreference.get()).into(avatar);
        mDrawer.setOnTouchListener((view, motionEvent) -> {
            Glide.with(view.getContext()).load(mAvatarPreference.get()).into(avatar);
            return false;
        });
        toggle.syncState();
        ArrayAdapter<String> adapter = new NavigationMenuAdapter(this,
                getResources().getStringArray(R.array.nav_menu), this);
        mNavigationListView.setAdapter(adapter);
        switchFragment(new ContactsFragment());
        onNewIntent(getIntent());
    }

    @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();
        mLoginPresenter.checkIfVoucherStillAvailable(this);
    }

    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 (mDrawer.isDrawerOpen(GravityCompat.START)) {
            mDrawer.closeDrawer(GravityCompat.START);
        }
        if (getSupportFragmentManager().getBackStackEntryCount() <= 1) {
            finish();
        }
        mLoginPresenter.checkIfVoucherStillAvailable(this);
        super.onBackPressed();
    }

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

    @Override
    public void goToProfile() {
        mLoginPresenter.checkIfVoucherStillAvailable(this);
        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() {
        mLoginPresenter.logout(Settings.Secure.getString(MainActivity.this.getContentResolver(),
                Settings.Secure.ANDROID_ID), true, this);
    }

    @Override
    public void goToLoginActivity() {
        if (isFinishing()) {
            return;
        }
        startActivity(new Intent(MainActivity.this, LoginActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
        finish();
    }

    @SuppressWarnings("unused")
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onInvalidToken(InvalidTokenEvent invalidTokenEvent) {
        Toast.makeText(this, R.string.login_again, Toast.LENGTH_LONG).show();
        logoutDirectly();
    }

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

    @Override
    protected void onDestroy() {
        EventBus.getDefault().unregister(this);
        mChatOpenedPref.set(false);
        if (!mLogoutClicked && getIntent().getBooleanExtra(LOGOUT, true)) {
            mLoginPresenter.tryToLogout(Settings.Secure.getString(this.getContentResolver(),
                    Settings.Secure.ANDROID_ID), this);
        }
        getIntent().removeExtra(LOGOUT);
        InjectionHelper.destroyMainComponents();
        super.onDestroy();
    }
}
