package com.ysnows.base.base

import android.annotation.SuppressLint
import android.util.Log
import com.ysnows.base.emptyview.callback.EmptyCallback
import com.ysnows.base.emptyview.callback.LoadingCallback
import com.ysnows.base.emptyview.callback.TimeoutCallback
import com.ysnows.base.emptyview.callback.ToLoginCallback
import com.ysnows.base.net.IResp
import com.ysnows.base.net.NetCode
import com.ysnows.base.net.PageResp
import com.ysnows.base.net.Resp
import com.ysnows.base.utils.exception.ExceptionUtils
import com.ysnows.base.view.BRView
import io.reactivex.Observable
import io.reactivex.ObservableEmitter

open class BRRepository : BRepository() {

    override fun view(): BRView<*> {
        return bView as BRView<*>
    }


    private lateinit var api: Observable<IResp<Collection<Any>>>
    private lateinit var apiFunc: suspend () -> IResp<*>
    var page = 0

    /**
     * 请求时, 缓存第一个数据
     *
     * @param <T>
     * @param key
     * @param clazz
     *
     * @return</T>
     *
     * */

    private suspend fun <T : IResp<*>> reqList(
            pageLoading: Boolean = true,
            func: suspend () -> T
    ): T {

        try {
            if (pageLoading) {
                bView.loadService?.showCallback(LoadingCallback::class.java)
            }
            val resp = func()
            view().onListReceive(resp)

            if (resp.code() == NetCode.CODE_OFFLINE) {
                when {
                    pageLoading -> {
                        bView.loadService?.showCallback(ToLoginCallback::class.java)
                    }
                    view().isNeedRefresh -> {
                        view().refreshing(false)
                    }
                }
                bView.toLogin()
                // bView.processCodeOffline()
            } else {

                if (page <= 1) {
                    if (resp.empty()) { //如果没有数据

                        view().loadService?.showCallback(EmptyCallback::class.java)

//                        if (pageLoading) {//列表还未有数据
//
//                            view().loadService?.showCallback(EmptyCallback::class.java)
//                        }


                    } else {
                        if (resp is PageResp<*>) {
                            view().adapter().setList(resp.data()?.list as Collection<Nothing>)
                        } else {
                            view().adapter().setList(resp.data() as Collection<Nothing>)
                        }

                        bView.loadService?.showSuccess()
//                        if (pageLoading) {
//                            bView.loadService?.showSuccess()
//                        }
                    }
                } else {
                    if (resp is PageResp<*>) {
                        view().adapter().addData(resp.data()?.list as Collection<Nothing>)
                    } else {
                        view().adapter().addData(resp.data() as Collection<Nothing>)
                    }
                }

                when {
                    view().isNeedRefresh -> {
                        view().refreshing(false)
                    }
                }


                if (resp.more(page, 10)) {
                    view().adapter().loadMoreModule.loadMoreComplete()
                } else {
                    //数据全部加载完毕
                    view().adapter().loadMoreModule.loadMoreEnd()
                }


            }
            return resp
        } catch (e: Exception) {
            e.printStackTrace()
            when {
                pageLoading -> {
                    bView.loadService?.showCallback(TimeoutCallback::class.java)
                }

                view().isNeedRefresh -> {
                    view().refreshing(false)
                }
                else -> {
                    view().toast(ExceptionUtils.getExceptionName(e))
                }
            }

            if (page >= 1) {
                view().adapter().loadMoreModule.loadMoreFail()
                page -= 1
            }


            return Resp<Any>(
                    NetCode.CODE_EXCEPTION,
                    msg = ExceptionUtils.getExceptionName(e)
            ) as T
        }
    }

    suspend fun <T : IResp<*>> reqFirstPage(pagable: Boolean, apiFunc: suspend () -> T): T {
        this.apiFunc = apiFunc
        page = 1
        return reqList(pagable, apiFunc)
    }

    suspend fun reqMore(): IResp<*> {
        autoPage()
        return reqList(false, this.apiFunc)
    }


    fun rxReqFirstPage(
            api: Observable<IResp<Collection<Any>>>,
            pagable: Boolean
    ): Observable<IResp<Collection<Any>>> {
        this.api = api;
        page = 1
        return rxReqList(api, pagable)
    }


    fun rxReqList(): Observable<IResp<Collection<Any>>> {
        return rxReqList(this.api, false)
    }


    fun rxReqList(observable: Observable<IResp<Collection<Any>>>): Observable<IResp<Collection<Any>>> {
        return rxReqList(observable, false)
    }

    @SuppressLint("CheckResult")
    fun rxReqList(
            observable: Observable<IResp<Collection<Any>>>,
            pageLoading: Boolean
    ): Observable<IResp<Collection<Any>>> {
        return Observable.create { emitter: ObservableEmitter<IResp<Collection<Any>>> ->
            rxReq(observable, pageLoading, false)
                    .doOnError { throwable: Throwable ->
                        throwable.printStackTrace()
                        if (page >= 1) {
                            view().adapter().loadMoreModule.loadMoreFail()
                            page -= 1
                        }
                        emitter.onError(throwable)
                    }
                    .subscribe({ res: IResp<Collection<Any>> ->
                        view().onListReceive(res)
                        if (page <= 1) {
                            if (res.empty()) { //如果没有数据
                                view().refreshing(false)
                                view().loadService!!.showCallback(EmptyCallback::class.java)
                            } else {
                                view().refreshing(false)
                                //Object data = res.data();
//                                if (data instanceof IResultList) {
//                                    adapter.setList(((IResultList) data).list());
//                                }
                                view().adapter().setList(res.data() as Collection<Nothing>)
                                view().loadService!!.showSuccess()
                            }
                            view().getTotal(res.total())
                        } else {
//                            Object data = res.data();
//                            if (data instanceof IResultList) {
//                                view().getAdapter().addData((((IResultList) data).list()));
//                            }
                            view().adapter().addData(res.data() as Collection<Nothing>)
                        }
                        if (res.more(page)) {
                            view().adapter().loadMoreModule.loadMoreComplete()
                        } else {
                            //数据全部加载完毕
                            view().adapter().loadMoreModule.loadMoreEnd()
                        }
                        emitter.onNext(res)
                    }, { throwable: Throwable? -> }) { emitter.onComplete() }
        }
    }

    fun autoPage(): Int {
        page += 1
        return page
    }
}
