package com.morihacky.android.rxjava.pagination;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import butterknife.Bind;
import butterknife.ButterKnife;
import com.morihacky.android.rxjava.MainActivity;
import com.morihacky.android.rxjava.R;
import com.morihacky.android.rxjava.fragments.BaseFragment;
import com.morihacky.android.rxjava.rxbus.RxBus;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.subjects.PublishSubject;
import rx.subscriptions.CompositeSubscription;

public class PaginationAutoFragment
      extends BaseFragment {

    @Bind(R.id.list_paging) RecyclerView _pagingList;
    @Bind(R.id.progress_paging) ProgressBar _progressBar;

    private PaginationAutoAdapter _adapter;
    private RxBus _bus;
    private PublishSubject<Integer> _paginator;
    private boolean _requestUnderWay = false;
    private CompositeSubscription _subscriptions;

    @Override
    public View onCreateView(LayoutInflater inflater,
                             @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        View layout = inflater.inflate(R.layout.fragment_pagination, container, false);
        ButterKnife.bind(this, layout);
        return layout;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        _bus = ((MainActivity) getActivity()).getRxBusSingleton();

        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        _pagingList.setLayoutManager(layoutManager);

        _adapter = new PaginationAutoAdapter(_bus);
        _pagingList.setAdapter(_adapter);

        _paginator = PublishSubject.create();
    }

    @Override
    public void onStart() {
        super.onStart();
        _subscriptions = new CompositeSubscription();

        Subscription s2 =//
              _paginator.onBackpressureDrop()
                    .doOnNext(i -> {
                        _requestUnderWay = true;
                        _progressBar.setVisibility(View.VISIBLE);
                    })
                    .concatMap(this::_itemsFromNetworkCall)
                    .observeOn(AndroidSchedulers.mainThread())
                    .map(items -> {
                        _adapter.addItems(items);
                        _adapter.notifyDataSetChanged();
                        return null;
                    })
                    .doOnNext(i -> {
                        _requestUnderWay = false;
                        _progressBar.setVisibility(View.INVISIBLE);
                    })
                    .subscribe();

        // I'm using an RxBus purely to hear from a nested button click
        // we don't really need Rx for this part. it's just easy ¯\_(ツ)_/¯
        Subscription s1 =//
              _bus.asObservable()//
                    .filter(o -> !_requestUnderWay)//
                    .subscribe(event -> {
                        if (event instanceof PaginationAutoAdapter.PageEvent) {

                            // trigger the paginator for the next event
                            int nextPage = _adapter.getItemCount();
                            _paginator.onNext(nextPage);
                        }
                    });

        _subscriptions.add(s1);
        _subscriptions.add(s2);

        _paginator.onNext(0);
    }

    @Override
    public void onStop() {
        super.onStop();
        _subscriptions.clear();
    }

    /**
     * Fake Observable that simulates a network call and then sends down a list of items
     */
    private Observable<List<String>> _itemsFromNetworkCall(int pageStart) {
        return Observable.just(true)//
              .observeOn(AndroidSchedulers.mainThread())//
              .delay(2, TimeUnit.SECONDS)
              .map(dummy -> {
                  List<String> items = new ArrayList<>();
                  for (int i = 0; i < 10; i++) {
                      items.add("Item " + (pageStart + i));
                  }
                  return items;
              });
    }
}

@@ -2319,18 +2319,27 @@
 ion s2 =
-//
+ _paginator
 %0A       
@@ -2345,26 +2345,16 @@
         
-_paginator
 .onBackp
@@ -2373,38 +2373,32 @@
 )%0A              
-      
 .doOnNext(i -%3E %7B
@@ -2390,38 +2390,32 @@
 doOnNext(i -%3E %7B%0A
-      
                 
@@ -2451,38 +2451,32 @@
                 
-      
 _progressBar.set
@@ -2511,39 +2511,27 @@
             
-     
- 
 %7D)%0A
-      
             
@@ -2578,38 +2578,32 @@
 )%0A              
-     
- 
 .observeOn(Andro
@@ -2639,30 +2639,24 @@
             
-      
 .map(items -
@@ -2669,38 +2669,32 @@
                 
-    
-  
 _adapter.addItem
@@ -2703,22 +2703,16 @@
 items);%0A
-      
         
@@ -2768,30 +2768,24 @@
             
-   
-   
 return null;
@@ -2791,38 +2791,32 @@
 ;%0A              
-      
 %7D)%0A             
@@ -2808,38 +2808,32 @@
 )%0A              
-  
-    
 .doOnNext(i -%3E %7B
@@ -2825,38 +2825,32 @@
 doOnNext(i -%3E %7B%0A
-      
                 
@@ -2887,38 +2887,32 @@
                 
-  
-    
 _progressBar.set
@@ -2945,38 +2945,32 @@
 ;%0A              
-      
 %7D)%0A             
@@ -2962,38 +2962,32 @@
 )%0A              
- 
-     
 .subscribe();%0A%0A 
@@ -3157,18 +3157,21 @@
 ion s1 =
-//
+ _bus
 %0A       
@@ -3177,20 +3177,16 @@
         
-_bus
 .asObser
@@ -3192,24 +3192,17 @@
 rvable()
-//%0A     
+%0A
         
@@ -3207,17 +3207,16 @@
         
- 
 .filter(
@@ -3238,22 +3238,17 @@
 nderWay)
-//%0A   
+%0A
         
@@ -3245,35 +3245,32 @@
 )%0A              
-   
 .subscribe(event
@@ -3293,22 +3293,16 @@
         
-   
-   
 if (even
@@ -3372,22 +3372,16 @@
         
-      
 // trigg
@@ -3438,22 +3438,16 @@
         
-  
-    
 int next
@@ -3474,30 +3474,24 @@
 temCount();%0A
-      
             
@@ -3543,38 +3543,26 @@
             
-      %7D%0A      
+%7D%0A
             
@@ -3980,16 +3980,31 @@
 servable
+%0A              
 .just(tr
@@ -4006,18 +4006,16 @@
 st(true)
-//
 %0A       
@@ -4063,18 +4063,16 @@
 hread())
-//
 %0A       

remove silly comment style helpers