package com.alsash.reciper.mvp.presenter;

import android.support.annotation.Nullable;

import com.alsash.reciper.database.entity.DaoSession;
import com.alsash.reciper.mvp.model.entity.Category;
import com.alsash.reciper.mvp.model.entity.Label;
import com.alsash.reciper.mvp.model.entity.Recipe;
import com.alsash.reciper.mvp.model.entity.database.CategoryMvpDb;
import com.alsash.reciper.mvp.model.entity.database.LabelMvpDb;
import com.alsash.reciper.mvp.model.entity.database.RecipeMvpDb;
import com.alsash.reciper.mvp.view.RecipeCategoriesView;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
import rx.subscriptions.CompositeSubscription;


public class RecipeCategoriesPresenter extends BaseRecipesPresenter<RecipeCategoriesView> {

    private final DaoSession session;
    private final List<Category> categories = new ArrayList<>();
    private final CompositeSubscription compositeSubscription = new CompositeSubscription();

    public RecipeCategoriesPresenter(DaoSession session) {
        this.session = session;
    }

    @Override
    public void initView() {
        if (getView() == null) return;
        loadCategories();
    }

    @Override
    public void completeView() {
        if (getView() == null) return;
        getView().setCategories(categories);
        getView().showCategories();
    }

    @Override
    public void setView(@Nullable RecipeCategoriesView view) {
        super.setView(view);
        if (view == null) { // DetachView
            compositeSubscription.unsubscribe();
            compositeSubscription.clear();
        }
    }

    private void loadCategories() {
        compositeSubscription.add(
                Observable.fromCallable(new Callable<Integer>() {
                    @Override
                    public Integer call() throws Exception {
                        return getCategories().size();
                    }
                }).observeOn(Schedulers.io())
                        .subscribeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Action1<Integer>() {
                            @Override
                            public void call(Integer size) {
                                if (size > 0) completeView();
                            }
                        })
        );
    }

    private synchronized List<Category> getCategories() {
        if (categories.size() > 0) return categories;
        List<com.alsash.reciper.database.entity.Category> dbCategories =
                session.getCategoryDao().queryBuilder().build().forCurrentThread().list();

        for (com.alsash.reciper.database.entity.Category categoryDb : dbCategories) {
            List<Recipe> categoryRecipes = new ArrayList<>();
            categories.add(new CategoryMvpDb(categoryDb.getId(), categoryDb.getName(),
                    categoryRecipes));

            for (com.alsash.reciper.database.entity.Recipe recipeDb : categoryDb.getRecipes()) {

                List<Label> recipeLabels = new ArrayList<>();
                categoryRecipes.add(new RecipeMvpDb(recipeDb.getId(), recipeDb.getName(),
                        categories.get(categories.size() - 1), recipeLabels));

                for (com.alsash.reciper.database.entity.Label labelDb : recipeDb.getLabels()) {
                    recipeLabels.add(new LabelMvpDb(labelDb.getId(), labelDb.getName(),
                            new ArrayList<Recipe>())); // Labels without inner recipes
                }

            }


        }
        return categories;
    }
}

@@ -2694,54 +2694,15 @@
 o().
-queryBuilder().build().forCurrentThread().list
+loadAll
 ();%0A
@@ -3592,25 +3592,24 @@
           %7D%0A
-%0A
             
@@ -3610,18 +3610,16 @@
       %7D%0A
-%0A%0A
         

Update ui