package com.zhaohaoting.framework.abs.task;

import android.arch.lifecycle.LifecycleOwner;

import com.zhaohaoting.framework.R;
import com.zhaohaoting.framework.mvchelper.mvc.RequestHandle;
import com.zhaohaoting.framework.mvchelper.mvc.ResponseSender;
import com.zhaohaoting.framework.abs.entity.ResultEntity;
import com.zhaohaoting.framework.mvchelper.okhttp.exception.RequestException;
import com.zhaohaoting.framework.mvchelper.task.IAsyncTask;
import com.zhaohaoting.framework.mvchelper.utils.NetworkUtils;
import com.zhaohaoting.framework.application.ZhtApplication;
import com.zhaohaoting.framework.requset.rxjava_retrofit.RxResultSubscriber;

import org.reactivestreams.Subscription;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

/**
 * author：Created by ZHT on 2017/11/13 14:17
 * email：526309416@qq.com
 * desc：列表 RESULT_DATA为BaseListEntity<DATA>或List<DATA></>
 */
@SuppressWarnings("unchecked")
public abstract class RxDataAsyncTask<DATA, RESULT_DATA extends ResultEntity<DATA>> implements IAsyncTask<DATA> {

    private boolean isRunning = true;
    private DoneActionRegister register;

    public RxDataAsyncTask() {
        register = new DoneActionRegister();
    }

    protected abstract Flowable<RESULT_DATA> loadDataAsyncTask();

    @Override
    public RequestHandle execute(ResponseSender<DATA> sender) {
        return load(sender, loadDataAsyncTask());
    }

    private RequestHandle load(final ResponseSender<DATA> sender, final Flowable<RESULT_DATA> observable) {
        final RxResultSubscriber subscriber = new RxResultSubscriber<DATA, RESULT_DATA>() {

            @Override
            public void onSubscribe(Subscription subscription) {
                register.addSubscription(subscription);
                subscription.request(Long.MAX_VALUE);//设置请求数
                isRunning = true;
            }

            @Override
            protected void onFailure(int code, String tipMsg) {
                isRunning = false;
                sender.sendError(new RequestException(tipMsg).setCode(code));
            }

            @Override
            protected void onSuccess(DATA dataSource) {
                sender.sendData(dataSource);
                isRunning = false;
            }
        };
        observable.doOnSubscribe(subscription -> {
            if (!NetworkUtils.hasNetwork(ZhtApplication.getContext())) {//没有网络
                subscription.cancel();
                isRunning = false;
                sender.sendError(new RequestException(ZhtApplication.getContext().getResources().getString(R.string.bad_network)));
            } else {
                isRunning = true;
            }
        }).subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
        return new RequestHandle() {
            @Override
            public void onDestroy(LifecycleOwner owner) {
                cancel();
            }

            @Override
            public void cancel() {
                for (Subscription subscription : register.subscriptions) {
                    subscription.cancel();
                }
            }

            @Override
            public boolean isRunning() {
                return isRunning;
            }
        };
    }

    public static class DoneActionRegister {
        private List<Subscription> subscriptions = new ArrayList<>();

        public void addSubscription(final Subscription subscription) {
            subscriptions.add(subscription);
        }
    }

}
