package com.zhaohaoting.framework.abs.task;

import android.arch.lifecycle.LifecycleOwner;

import com.zhaohaoting.framework.mvchelper.mvc.RequestHandle;
import com.zhaohaoting.framework.mvchelper.mvc.ResponseSender;
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.R;
import com.zhaohaoting.framework.ZhtLibrary;
import com.zhaohaoting.framework.requset.rxjava_retrofit.RxResultSimpleSubscriber;

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：子类可定制 根据结果BASE_DATA判断成功返回数据还是失败
 */
@SuppressWarnings("unchecked")
public abstract class RxCustomDataAsyncTask<DATA, BASE_DATA> implements IAsyncTask<DATA> {

    private boolean isRunning = true;
    private DoneActionRegister register;

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

    protected abstract Flowable<BASE_DATA> loadDataAsyncTask();

    protected abstract void loadSubscriberOnNext(BASE_DATA data, ResponseSender<DATA> sender);

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

    private RequestHandle load(final ResponseSender<DATA> sender, final Flowable<BASE_DATA> observable) {
        final RxResultSimpleSubscriber subscriber = new RxResultSimpleSubscriber<BASE_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
            public void onNext(BASE_DATA data) {
                isRunning = false;
                loadSubscriberOnNext(data, sender);
            }
        };
        observable.doOnSubscribe(new Consumer<Subscription>() {
            @Override
            public void accept(Subscription subscription) throws Exception {
                if (!NetworkUtils.hasNetwork(ZhtLibrary.getContext())) {//没有网络
                    subscription.cancel();
                    isRunning = false;
                    sender.sendError(new RequestException(ZhtLibrary.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);
        }
    }

}
