package it.integry.integrywmsnative.gest.main;

import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;

import androidx.annotation.IdRes;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.widget.SearchView;
import androidx.core.view.GravityCompat;
import androidx.databinding.DataBindingUtil;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import com.google.android.material.navigation.NavigationView;

import java.util.List;

import javax.inject.Inject;

import it.integry.integrywmsnative.MainApplication;
import it.integry.integrywmsnative.R;
import it.integry.integrywmsnative.core.class_router.configs.BaseMenuConfiguration;
import it.integry.integrywmsnative.core.class_router.configs.MenuConfiguration;
import it.integry.integrywmsnative.core.context.MainContext;
import it.integry.integrywmsnative.core.data_recover.ColliDataRecoverService;
import it.integry.integrywmsnative.core.expansion.BaseActivity;
import it.integry.integrywmsnative.core.expansion.OnSingleClickListener;
import it.integry.integrywmsnative.core.interfaces.IFilterableFragment;
import it.integry.integrywmsnative.core.interfaces.ILifecycleFragment;
import it.integry.integrywmsnative.core.interfaces.IPoppableActivity;
import it.integry.integrywmsnative.core.interfaces.IScrollableFragment;
import it.integry.integrywmsnative.core.interfaces.ISearchableFragment;
import it.integry.integrywmsnative.core.interfaces.ISelectAllFragment;
import it.integry.integrywmsnative.core.interfaces.ITitledFragment;
import it.integry.integrywmsnative.core.menu.MenuService;
import it.integry.integrywmsnative.core.rest.watcher.ServerStatusChecker;
import it.integry.integrywmsnative.core.update.UpdatesManager;
import it.integry.integrywmsnative.core.utility.UtilityContext;
import it.integry.integrywmsnative.databinding.ActivityMainBinding;
import it.integry.integrywmsnative.gest.login.LoginActivity;
import it.integry.integrywmsnative.gest.settings.MainSettingsFragment;
import it.integry.integrywmsnative.view.dialogs.DialogProgressView;

public class MainActivity extends BaseActivity
        implements NavigationView.OnNavigationItemSelectedListener, IPoppableActivity {

    private ActivityMainBinding mBinding;

    private boolean firstCheckExecution = true;
    private boolean mIsOnline = false;

    @Inject
    ColliDataRecoverService mColliDataRecoverService;

    @Inject
    MenuService menuService;

    @Inject
    MainContext mainContext;

    @Inject
    UpdatesManager updatesManager;

    @Inject
    DialogProgressView mDialogProgressView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        MainApplication.appComponent
                .mainActivityComponent()

                .create()
                .inject(this);

        mBinding = DataBindingUtil.inflate(LayoutInflater.from(this), R.layout.activity_main, null, false);
        setContentView(mBinding.getRoot());

        updatesManager.init(this);
        UtilityContext.initMainActivity(this);

        setSupportActionBar(mBinding.appBarMain.toolbar);
        getSupportActionBar().setDisplayShowTitleEnabled(false);


        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, mBinding.drawerLayout, mBinding.appBarMain.toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        mBinding.drawerLayout.setDrawerListener(toggle);
        toggle.syncState();


        mBinding.navView.setNavigationItemSelectedListener(this);
        mBinding.appBarMain.mainSearch.setVisibility(View.GONE);

        initGestMenu();
        if (savedInstanceState == null) openMain();

        init();

    }

    private void startLoginActivity() {
        this.finish();
        Intent myIntent = new Intent(this, LoginActivity.class);
        startActivity(myIntent);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            onBackPressed();
            return true;
        }
        return super.onKeyUp(keyCode, event);
    }


    @Override
    public void onBackPressed() {
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            int count = getSupportFragmentManager().getBackStackEntryCount();

            if (count == 0) {
                super.onBackPressed();
            } else {
                Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.frame_container);
                if (fragment instanceof ILifecycleFragment) {
                    ((ILifecycleFragment) fragment).onPreDestroy(this::pop);
                } else pop();
                // getSupportFragmentManager().popBackStack();

            }
        }
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return true;
    }

    public void setMenuItem(@IdRes int menuId) {
        mBinding.navView.setCheckedItem(menuId);
        onNavigationItemSelected(mBinding.navView.getMenu().findItem(menuId));
    }

    @Override
    public boolean onNavigationItemSelected(MenuItem item) {

        mBinding.appBarMain.elevatedToolbar.resetAll();

        // Handle navigation view item clicks here.
        Fragment fragment = null;
        int id = item.getItemId();

        BaseMenuConfiguration.MenuItem menuItem = getMenuItem(id);

        if (menuItem != null) {
            fragment = menuItem.getFragmentFactory().run();
            this.adaptViewToFragment(fragment);
        } else {
            if (id == R.id.nav_home) {
                this.pop();
            } else if (id == R.id.nav_settings) {
                fragment = new MainSettingsFragment();
                this.adaptViewToFragment(fragment);
            } else if (id == R.id.nav_logout) {
                ServerStatusChecker.dispose();
                this.mainContext.logout(() -> {
                    startLoginActivity();
                });
            }
        }

        changeContentFragment(fragment, true);

        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }


    private void initGestMenu() {
        Menu menu = mBinding.navView.getMenu();

        menu.add(R.id.nav_home, R.id.nav_home, 0, R.string.home)
                .setIcon(R.drawable.ic_black_home);

        MenuConfiguration baseMenuConfiguration = new MenuConfiguration();
        List<MenuConfiguration.MenuGroup> menuGroups = baseMenuConfiguration.getGroups();

        for (MenuConfiguration.MenuGroup menuGroup : menuGroups) {
            try {

                if (menuService.isGroupEnabled(menuGroup)) {
                    SubMenu subMenu = menu.addSubMenu(menuGroup.getGroupText());

                    for (MenuConfiguration.MenuItem menuItem : menuGroup.getItems()) {

                        if (menuService.isItemEnabled(menuItem)) {
                            subMenu
                                    .add(menuGroup.getGroupId(), menuItem.getID(), 0, menuItem.getTitleText())
                                    .setIcon(menuItem.getDrawerIcon());
                        }

                    }
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }


        SubMenu subMenu = menu.addSubMenu(R.string.other);
        subMenu.add(R.id.nav_home, R.id.nav_settings, 0, R.string.general_settings)
                .setIcon(R.drawable.ic_settings_24dp);
        subMenu.add(R.id.nav_logout, R.id.nav_logout, 0, R.string.logout)
                .setIcon(R.drawable.ic_logout_24dp);
    }

    private MenuConfiguration.MenuItem getMenuItem(@IdRes int menuId) {
        BaseMenuConfiguration menuConfiguration = new MenuConfiguration();
        List<MenuConfiguration.MenuGroup> menuGroups = menuConfiguration.getGroups();

        BaseMenuConfiguration.MenuItem menuItemToReturn = null;

        for (MenuConfiguration.MenuGroup menuGroup : menuGroups) {
            for (MenuConfiguration.MenuItem menuItem : menuGroup.getItems()) {
                if (menuId == menuItem.getID()) {
                    menuItemToReturn = menuItem;
                    break;
                }
            }

            if (menuItemToReturn != null) break;
        }


        return menuItemToReturn;
    }

    private void openMain() {
        MainFragment mainFragment = MainFragment.newInstance();

        adaptViewToFragment(mainFragment);

        changeContentFragment(mainFragment, false);
        mBinding.navView.setCheckedItem(R.id.nav_home);
    }

    @Override
    public void pop() {

        int count = getSupportFragmentManager().getBackStackEntryCount();
        for (int i = 0; i < count; i++) {
            getSupportFragmentManager().popBackStack();
        }
    }

    private void adaptViewToFragment(Fragment fragment) {
        if (fragment instanceof ISearchableFragment) {
            mBinding.appBarMain.mainSearch.setOnQueryTextListener((SearchView.OnQueryTextListener) fragment);
            mBinding.appBarMain.mainSearch.setVisibility(View.VISIBLE);
            mBinding.appBarMain.mainSearch.setOnSearchClickListener(v -> {
                ((ISearchableFragment) fragment).onSearchEnabled();
                mBinding.appBarMain.toolbarTitleLeft.setVisibility(View.GONE);
            });

            mBinding.appBarMain.mainSearch.setOnCloseListener(() -> {
                ((ISearchableFragment) fragment).onSearchDisabled();
                mBinding.appBarMain.toolbarTitleLeft.setVisibility(View.VISIBLE);
                return false;
            });

            ((ISearchableFragment) fragment).addOnPreDestroy(() -> {
                mBinding.appBarMain.mainSearch.setIconified(true);
                mBinding.appBarMain.mainSearch.setVisibility(View.GONE);
            });
        } else {
            mBinding.appBarMain.mainSearch.setOnQueryTextListener(null);
            mBinding.appBarMain.mainSearch.setVisibility(View.GONE);
            mBinding.appBarMain.mainSearch.setOnSearchClickListener(null);
            mBinding.appBarMain.mainSearch.setOnCloseListener(null);
        }


        if (fragment instanceof ITitledFragment && !(fragment instanceof MainFragment)) {
            mBinding.appBarMain.toolbarTitleCenteredLayout.setVisibility(View.GONE);
            mBinding.appBarMain.toolbarTitleLeft.setVisibility(View.VISIBLE);
            ((ITitledFragment) fragment).onCreateActionBar(mBinding.appBarMain.toolbarTitleLeft, this);
            ((ITitledFragment) fragment).addOnPreDestroy(() -> {
                mBinding.appBarMain.toolbarTitleCenteredLayout.setVisibility(View.VISIBLE);
                mBinding.appBarMain.toolbarTitleLeft.setVisibility(View.GONE);
            });
        } else {
            mBinding.appBarMain.toolbarTitleCenteredLayout.setVisibility(View.VISIBLE);
            mBinding.appBarMain.toolbarTitleLeft.setVisibility(View.GONE);
        }

        if (fragment instanceof IScrollableFragment) {
            ((IScrollableFragment) fragment).setScrollToolbar(mBinding.appBarMain.elevatedToolbar);
            ((IScrollableFragment) fragment).addOnPreDestroy(() -> {
                mBinding.appBarMain.elevatedToolbar.resetAll();
            });
        }

        if (fragment instanceof ISelectAllFragment && ((ISelectAllFragment) fragment).isSelectAllButtonEnabled()) {
            mBinding.appBarMain.mainSelectAll.setVisibility(View.VISIBLE);
            mBinding.appBarMain.mainSelectAll.setOnClickListener(new OnSingleClickListener() {
                @Override
                public void onSingleClick(View v) {
                    ((ISelectAllFragment) fragment).onSelectAll();
                }
            });
            ((ISelectAllFragment) fragment).addOnPreDestroy(() -> {
                mBinding.appBarMain.mainSelectAll.setVisibility(View.GONE);
                mBinding.appBarMain.mainSelectAll.setOnClickListener(null);
            });
        }

        if (fragment instanceof IFilterableFragment) {
            mBinding.appBarMain.mainFilter.setVisibility(View.VISIBLE);
            mBinding.appBarMain.mainFilter.setOnClickListener(new OnSingleClickListener() {
                @Override
                public void onSingleClick(View v) {
                    ((IFilterableFragment) fragment).onFilterClick();
                }
            });

            ((IFilterableFragment) fragment).addOnPreDestroy(() -> {
                mBinding.appBarMain.mainFilter.setVisibility(View.GONE);
                mBinding.appBarMain.mainFilter.setOnClickListener(null);
            });
        } else {
            mBinding.appBarMain.mainFilter.setVisibility(View.GONE);
            mBinding.appBarMain.mainFilter.setOnClickListener(null);
        }
    }

    private void changeContentFragment(Fragment fragment, boolean addToBackStack) {
        if (fragment != null) {
            FragmentManager fragmentManager = getSupportFragmentManager();
            FragmentTransaction ft = fragmentManager
                    .beginTransaction()
                    .replace(R.id.frame_container, fragment);

            if (addToBackStack) ft.addToBackStack(fragment.getTag());

            ft.commit();
            //fragmentManager.executePendingTransactions();

        }
    }


    private void init() {

//        ServerStatusChecker.getInstance().addCallback(value -> {
//            if(value && (!mIsOnline || firstCheckExecution)){
//
//                SettingsManager.loadDBVariables(() -> {
//                        mIsOnline = true;
//                        firstCheckExecution = false;
//
//                    }, ex -> {
//                        //mNoConnectionLayout.expand(true);
//                        if(mIsOnline) mIsOnline = false;
//                    }
//                );
//
//            } else if(!value && mIsOnline){
//                mIsOnline = false;
//            }
//        });

    }


}
