package ee.ria.DigiDoc.android.main.home;

import android.annotation.SuppressLint;
import android.content.Context;
import android.support.design.widget.BottomNavigationView;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

import ee.ria.DigiDoc.R;
import ee.ria.DigiDoc.android.Application;
import ee.ria.DigiDoc.android.crypto.CryptoHomeView;
import ee.ria.DigiDoc.android.eid.EIDHomeView;
import ee.ria.DigiDoc.android.signature.home.SignatureHomeView;
import ee.ria.DigiDoc.android.utils.ViewDisposables;
import ee.ria.DigiDoc.android.utils.mvi.MviView;
import io.reactivex.Observable;
import io.reactivex.subjects.PublishSubject;
import io.reactivex.subjects.Subject;

import static com.jakewharton.rxbinding2.support.design.widget.RxBottomNavigationView.itemSelections;
import static ee.ria.DigiDoc.android.utils.Predicates.duplicates;
import static ee.ria.DigiDoc.android.utils.rxbinding.app.RxDialog.cancels;

@SuppressLint("ViewConstructor")
public final class HomeView extends LinearLayout implements MviView<Intent, ViewState> {

    public interface HomeViewChild {

        HomeToolbar homeToolbar();

        Observable<Boolean> navigationViewVisibility();
    }

    private final String eidScreenId;

    private final FrameLayout navigationContainerView;
    private final BottomNavigationView navigationView;
    private final HomeMenuDialog menuDialog;
    private final HomeMenuView menuView;

    private final HomeViewModel viewModel;
    private final ViewDisposables disposables = new ViewDisposables();

    private final Subject<Intent.MenuIntent> menuIntentSubject = PublishSubject.create();
    private final Subject<Intent.NavigationVisibilityIntent> navigationVisibilityIntentSubject =
            PublishSubject.create();

    public HomeView(Context context, String screenId) {
        super(context);
        eidScreenId = screenId + "eid";
        setOrientation(VERTICAL);
        inflate(context, R.layout.main_home, this);
        navigationContainerView = findViewById(R.id.mainHomeNavigationContainer);
        navigationView = findViewById(R.id.mainHomeNavigation);
        menuDialog = new HomeMenuDialog(context);
        menuView = menuDialog.getMenuView();
        viewModel = Application.component(context).navigator().viewModel(screenId,
                HomeViewModel.class);
        viewModel.eidScreenId(eidScreenId);
    }

    @Override
    public void render(ViewState state) {
        View currentNavigationView = navigationContainerView.getChildAt(0);
        if (currentNavigationView == null || currentNavigationView.getId() != state.viewId()) {
            FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
                    FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
            View view;
            if (state.viewId() == R.id.mainHomeSignature) {
                view = new SignatureHomeView(getContext());
            } else if (state.viewId() == R.id.mainHomeCrypto) {
                view = new CryptoHomeView(getContext());
            } else if (state.viewId() == R.id.mainHomeEID) {
                view = new EIDHomeView(getContext(), eidScreenId);
            } else {
                throw new IllegalArgumentException("Unknown view ID " + state.viewId());
            }
            view.setId(state.viewId());
            navigationContainerView.removeAllViews();
            navigationContainerView.addView(view, layoutParams);

            HomeViewChild homeViewChild = (HomeViewChild) view;
            homeViewChild.homeToolbar().overflowButtonClicks()
                    .map(ignored -> Intent.MenuIntent.state(true))
                    .subscribe(menuIntentSubject);
            homeViewChild.navigationViewVisibility()
                    .map(Intent.NavigationVisibilityIntent::create)
                    .subscribe(navigationVisibilityIntentSubject);
        }

        if (state.menuOpen()) {
            menuDialog.show();
        } else {
            menuDialog.dismiss();
        }

        navigationView.setVisibility(state.navigationVisible() ? VISIBLE : GONE);
    }

    private Observable<Intent.InitialIntent> initialIntent() {
        return Observable.just(Intent.InitialIntent.create());
    }

    private Observable<Intent.NavigationIntent> navigationIntent() {
        return itemSelections(navigationView)
                .filter(duplicates())
                .map(item -> Intent.NavigationIntent.create(item.getItemId()));
    }

    private Observable<Intent.MenuIntent> menuIntent() {
        return Observable.merge(
                menuIntentSubject,
                cancels(menuDialog).map(ignored -> Intent.MenuIntent.state(false)),
                menuView.closeButtonClicks().map(ignored -> Intent.MenuIntent.state(false)),
                menuView.itemClicks().map(Intent.MenuIntent::navigate));
    }

    private Observable<Intent.NavigationVisibilityIntent> navigationVisibilityIntent() {
        return navigationVisibilityIntentSubject;
    }

    @SuppressWarnings("unchecked")
    @Override
    public Observable<Intent> intents() {
        return Observable.mergeArray(initialIntent(), navigationIntent(), menuIntent(),
                navigationVisibilityIntent());
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        disposables.attach();
        disposables.add(viewModel.viewStates().filter(duplicates()).subscribe(this::render));
        viewModel.process(intents());
    }

    @Override
    protected void onDetachedFromWindow() {
        menuDialog.dismiss();
        disposables.detach();
        super.onDetachedFromWindow();
    }
}

@@ -108,16 +108,90 @@
 ontext;%0A
+import android.os.Parcelable;%0Aimport android.support.annotation.Nullable;%0A
 import a
@@ -237,24 +237,57 @@
 gationView;%0A
+import android.util.SparseArray;%0A
 import andro
@@ -1898,24 +1898,87 @@
 .create();%0A%0A
+    @Nullable private SparseArray%3CParcelable%3E hierarchyState;%0A%0A
     public H
@@ -3599,24 +3599,179 @@
 AllViews();%0A
+            if (hierarchyState != null) %7B%0A                view.restoreHierarchyState(hierarchyState);%0A                hierarchyState = null;%0A            %7D%0A
             
@@ -5987,32 +5987,32 @@
 ables.detach();%0A
-
         super.on
@@ -6038,11 +6038,196 @@
 );%0A    %7D
+%0A%0A    @Override%0A    public void restoreHierarchyState(SparseArray%3CParcelable%3E container) %7B%0A        super.restoreHierarchyState(container);%0A        this.hierarchyState = container;%0A    %7D
 %0A%7D%0A

Save home navigation view state