package alekseyprochukhan.android.demo.mvvm.ui.activities;


import java.util.concurrent.TimeUnit;

import alekseyprochukhan.android.demo.mvvm.data.IDataModel;
import alekseyprochukhan.android.demo.mvvm.data.model.Video;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.observers.DisposableObserver;
import io.realm.RealmResults;
import timber.log.Timber;

/**
 * Main activity view model.
 *
 * Created by Aleksey Prochukhan <[email protected]>
 * 14/05/2017
 */
public class MainActivityVM {

    /** Keeps all active subscriptions and releases them when activity terminates. */
    private CompositeDisposable mDisposable = new CompositeDisposable();


    /** Data model to be used by this view model. */
    private IDataModel mDataModel;


    public MainActivityVM(IDataModel dataModel) {
        mDataModel = dataModel;
    }

    /**
     * Disposes all active subscriptions.
     */
    public void dispose() {
        try {
            mDisposable.dispose();
        } catch (Throwable t) {
            Timber.e(t, "Failed to unsubscribe from data model!");
        }
    }

    /**
     * Used to subscribe view model to the video list pull-to-refresh events.
     */
    public Disposable subscribeOnRefreshVideos(Observable<Object> refreshVideos) {
        return refreshVideos
                .debounce(500, TimeUnit.MILLISECONDS)
                .subscribeOn(AndroidSchedulers.mainThread())
                .subscribe((Object) -> mDataModel.fetchVideosFromServer(null));
    }

    /**
     * Used to subscribe view model to the video list scroll to the bottom events.
     */
    public Disposable subscribeOnLoadNextVideos(Observable<String> loadNextVideos) {
        return loadNextVideos
                .subscribeOn(AndroidSchedulers.mainThread())
                .distinctUntilChanged()
                .subscribe((String token) -> mDataModel.fetchVideosFromServer(token));
    }

    /**
     * Loads up-to-date list of videos.
     */
    public Observable<RealmResults<Video>> getVideos() {
        return mDataModel.getVideos(false);
    }

    /**
     * Subscribes given observer to the network usage events.
     */
    public DisposableObserver<Boolean> isNetworkInUse(DisposableObserver<Boolean> observer) {
        return mDataModel.isNetworkInUse(observer);
    }
}