package com.yidianling.home.presenter

import android.annotation.SuppressLint
import com.google.gson.Gson
import com.ydl.ydlcommon.base.BaseApp
import com.ydl.ydlcommon.data.http.RxUtils
import com.ydl.ydlcommon.data.http.ThrowableConsumer
import com.ydl.ydlcommon.modular.ModularServiceManager
import com.ydl.ydlcommon.utils.SharedPreferencesEditor
import com.ydl.ydlcommon.utils.ThreadUtils
import com.yidianling.common.tools.LogUtil
import com.yidianling.common.tools.RxAppTool
import com.yidianling.consultant.api.IConsultantService
import com.yidianling.home.constract.HomeViewConfig
import com.yidianling.home.constract.IHomeContract
import com.yidianling.home.model.HomeModelImpl
import com.yidianling.home.model.bean.*
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.Action
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers


/**
 * @author <a href="https://www.jianshu.com/u/c1e5310dd724">xujian</a>
 * @描述:
 * @Copyright Copyright (c) 2019
 * @Company 壹点灵
 * @date 2019/02/13
 */
class HomePresenterImpl: BaseHomePresenterImpl<IHomeContract.View, IHomeContract.Model>(), IHomeContract.Presenter {
    override fun createModel(): IHomeContract.Model {
        return HomeModelImpl()
    }

    /**
     * 获取首页数据请求
     */
    @SuppressLint("CheckResult")
    override fun loadHomeData() {
        disposeHome()
        val homeList: MutableList<HomePagerDataBean> = mutableListOf()
        LogUtil.d("mConsultType-loadHomeData:$mConsultType")

        val headerObservable = mModel.headerRequest()
            .compose(RxUtils.applySchedulers(mView)).map { it ->

                mView.homeHeadResponse(it)
                //获取咨询分类后，再次请求咨询模块数据，防止出现默认分类为空，数据不对
                if (it.consultCategoryData != null && it.consultCategoryData!!.isNotEmpty()) {
                    //咨询分类和缓存分类不一致，重新加载咨询列表数据
                    if (it.consultCategoryData!![0].id.toString() != mConsultType) {
                        getConsultData("${it.consultCategoryData!![0].id}", 0, false)
                    }
                }
                //保存热门搜索列表
                it.keywordData?.let {
                    ModularServiceManager.provide(IConsultantService::class.java).setHotSearch(it)
                }
                //首页头部数据 分类 & Banner
                homeList.add(
                    getHomeItemFromTempData(
                        it,
                        HomeViewConfig.getOrder().bannerIndex!!
                    )
                )
            }

        val consultObservable = mModel.consultRequest(mConsultType)
            .compose(RxUtils.applySchedulers(mView)).map {
                //首页咨询数据
                homeList.add(getHomeItemFromTempData(it, HomeViewConfig.getOrder().consultIndex!!))
            }

        //GoodType为空 获取默认类型
        val confideObservable = mModel.confideRequest(mConfideType)
            .compose(RxUtils.applySchedulers(mView)).map {
                //首页倾述数据
                homeList.add(getHomeItemFromTempData(it, HomeViewConfig.getOrder().confideIndex!!))
            }

        val courseObservable = mModel.courseRequest()
            .compose(RxUtils.applySchedulers(mView)).map {
                //首页课程数据
                homeList.add(getHomeItemFromTempData(it, HomeViewConfig.getOrder().courseIndex!!))
            }

        val testObservable = mModel.testRequest()
            .compose(RxUtils.applySchedulers(mView)).map {
                //首页测试数据
                val homeTestBean = HomeTestBean()
                homeTestBean.testItemList = it.data
                homeList.add(
                    getHomeItemFromTempData(
                        homeTestBean,
                        HomeViewConfig.getOrder().testsIndex!!
                    )
                )
            }

        val askObservable = mModel.askRequest()
            .compose(RxUtils.applySchedulers(mView)).map {
                //首页问答数据
                homeList.add(getHomeItemFromTempData(it, HomeViewConfig.getOrder().dynamicIndex!!))
            }

        val meditationObservable = mModel.getMeditation()
            .compose(RxUtils.applySchedulers(mView)).map {
                homeList.add(getHomeItemFromTempData(it,HomeViewConfig.getOrder().museIndex!!))
            }

        val fmObservable = mModel.fmRequest()
            .compose(RxUtils.applySchedulers(mView)).map {
                //首页电台数据
                homeList.add(
                    getHomeItemFromTempData(
                        it,
                        HomeViewConfig.getOrder().fmIndex!!
                    )
                )
            }

        val articleObservable = mModel.articleRequest()
            .compose(RxUtils.applySchedulers(mView)).map {
                //首页文章数据
                homeList.add(getHomeItemFromTempData(it, HomeViewConfig.getOrder().articleIndex!!))
            }

        //动态添加各业务模块请求
        val mergeArrays:ArrayList<Observable<Boolean?>> = arrayListOf()
        if (HomeViewConfig.getOrder().bannerIndex!=null){
            mergeArrays.add(headerObservable)
        }

        if (HomeViewConfig.getOrder().consultIndex!=null){
            mergeArrays.add(consultObservable)
        }
        if (HomeViewConfig.getOrder().courseIndex!=null){
            mergeArrays.add(courseObservable)
        }
        if (HomeViewConfig.getOrder().confideIndex!=null){
            mergeArrays.add(confideObservable)
        }
        if (HomeViewConfig.getOrder().testsIndex!=null){
            mergeArrays.add(testObservable)
        }
        if (HomeViewConfig.getOrder().dynamicIndex!=null){
            mergeArrays.add(askObservable)
        }
        if (HomeViewConfig.getOrder().museIndex!=null){
            mergeArrays.add(meditationObservable)
        }
        if (HomeViewConfig.getOrder().fmIndex!=null){
            mergeArrays.add(fmObservable)
        }
        if (HomeViewConfig.getOrder().articleIndex!=null){
            mergeArrays.add(articleObservable)
        }

        //将集合转化为数组
        Observable.mergeArray(*mergeArrays.toTypedArray())
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(Consumer {}, object : ThrowableConsumer() {
                override fun accept(msg: String) {
                    mView.homeDataFail(msg)
                    mHomeDisposable?.dispose()
                }
            }, Action {
                LogUtil.i("homeList Size:"+homeList.size+" - "+mergeArrays.size)
                if (homeList.size != mergeArrays.size){
                    mView.homeDataFail("")
                    return@Action
                }

                if (HomeViewConfig.getOrder().buttonIndex != null){
                    homeList.add(HomePagerDataBean(HomeViewConfig.getOrder().buttonIndex!!))
                }
                if (HomeViewConfig.getOrder().footerIndex!=null){
                    homeList.add(HomePagerDataBean(HomeViewConfig.getOrder().footerIndex!!))
                }
                homeList.sortWith(compareBy { it.type })

                mView.homeDataResponse(homeList)

                //更新本地缓存数据
                ThreadUtils.doOnThread(object : ThreadUtils.ThreadTask{
                    override fun doOnThread() {
                        SharedPreferencesEditor.putString(CACHE_HOME_PAGER_DATA, Gson().toJson(homeList))
                        SharedPreferencesEditor.putString(
                            HOME_PAGER_DATA_CACHE_VERISON,
                            RxAppTool.getAppVersionCode(BaseApp.getApp()).toString()
                        )
                    }
                })
            })
    }

    override fun refreshHomeData() {
        val homeItemFromTempData = getHomeItemFromTempData(
            HomeHeaderBean(true),
            HomeViewConfig.getOrder().bannerIndex!!
        )

        mConsultType =
            if (homeItemFromTempData.headerBean?.listenCategoryDate == null || homeItemFromTempData.headerBean?.listenCategoryDate!!.isEmpty()) {
                "1"
            } else {
                homeItemFromTempData.headerBean?.consultCategoryData!![0].id.toString()
            }

        mConfideType = ""

        mView.resetModuleTabPosition()
        loadHomeData()
    }

    override fun saveTempData(list: MutableList<HomePagerDataBean>) {
        val homeBean = HomePagerDataBean()
        for (dataBean in list) {
            when (dataBean.type) {
                HomeViewConfig.getOrder().bannerIndex -> {
                    homeBean.headerBean = dataBean.headerBean
                    dataBean.headerBean?.keywordData?.let {
                        ModularServiceManager.provide(IConsultantService::class.java)
                            .setHotSearch(it)
                    }
                }
                HomeViewConfig.getOrder().consultIndex -> {
                    homeBean.consultBean = dataBean.consultBean
                }
                HomeViewConfig.getOrder().confideIndex -> {
                    homeBean.confideBean = dataBean.confideBean
                }
                HomeViewConfig.getOrder().courseIndex -> {
                    homeBean.courseBean = dataBean.courseBean
                }
                HomeViewConfig.getOrder().testsIndex -> {
                    homeBean.testListBean = dataBean.testListBean
                }
                HomeViewConfig.getOrder().dynamicIndex -> {
                    mHomeAskBean = dataBean.askBean
                    homeBean.askBean = dataBean.askBean
                }
                HomeViewConfig.getOrder().museIndex -> {
                    homeBean.museBean = dataBean.museBean
                }
                HomeViewConfig.getOrder().fmIndex -> {
                    homeBean.fmBean = dataBean.fmBean
                }
                HomeViewConfig.getOrder().articleIndex -> {
                    homeBean.articleBean = dataBean.articleBean
                }
            }
        }
        homeTempData = homeBean
    }

    override fun getHomeItemFromTempData(
        dataBean: HomeItemBaseBean,
        type: Int
    ): HomePagerDataBean {

        val item = HomePagerDataBean(type)

        when (type) {
            HomeViewConfig.getOrder().bannerIndex -> {
                item.headerBean =
                    if (dataBean.isRealEmpty || dataBean !is HomeHeaderBean) homeTempData.headerBean else dataBean
            }
            HomeViewConfig.getOrder().consultIndex -> {
                item.consultBean =
                    if (dataBean.isRealEmpty || dataBean !is HomeConsultBean) homeTempData.consultBean else dataBean
            }
            HomeViewConfig.getOrder().confideIndex -> {
                item.confideBean =
                    if (dataBean.isRealEmpty || dataBean !is HomeConfideBean) homeTempData.confideBean else dataBean
            }
            HomeViewConfig.getOrder().courseIndex -> {
                item.courseBean =
                    if (dataBean.isRealEmpty || dataBean !is HomeCourseBean) homeTempData.courseBean else dataBean
            }
            HomeViewConfig.getOrder().testsIndex -> {
                item.testListBean =
                    if (dataBean.isRealEmpty || dataBean !is HomeTestBean) homeTempData.testListBean else dataBean.testItemList
            }
            HomeViewConfig.getOrder().dynamicIndex -> {
                item.askBean =
                    if (dataBean.isRealEmpty || dataBean !is HomeAskBean) homeTempData.askBean else dataBean
                mHomeAskBean = item.askBean
            }
            HomeViewConfig.getOrder().museIndex -> {
                item.meditationBean =
                    if (dataBean.isRealEmpty || dataBean !is MeditationModuleBean) homeTempData.meditationBean else dataBean
            }
            HomeViewConfig.getOrder().fmIndex -> {
                item.fmBean =
                    if (dataBean.isRealEmpty || dataBean !is HomeFMBean) homeTempData.fmBean else dataBean
            }
            HomeViewConfig.getOrder().articleIndex -> {
                item.articleBean =
                    if (dataBean.isRealEmpty || dataBean !is HomeArticleBean) homeTempData.articleBean else dataBean
            }
        }
        return item
    }
}