package com.gh.gamecenter.subject

import android.app.Application
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.common.exposure.ExposureUtils
import com.gh.common.util.AdHelper
import com.gh.gamecenter.common.baselist.ListViewModel
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.baselist.LoadType
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.core.utils.TimeUtils
import com.gh.gamecenter.entity.SubjectData
import com.gh.gamecenter.entity.SubjectSettingEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.PageLocation
import com.gh.gamecenter.feature.entity.TagStyleEntity
import com.gh.gamecenter.feature.exposure.ExposureConstants
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import retrofit2.HttpException

open class SubjectListViewModel(
    application: Application,
    var subjectData: SubjectData,
    var pageLocation: PageLocation,
    var exposureSourceList: List<ExposureSource>?,
    var columnCollectionId: String?,
) : ListViewModel<GameEntity, GameEntity>(application) {

    // 供统计用
    var selectedLabelList = arrayListOf<String>()
    var selectedFilterSize = SubjectSettingEntity.Size(text = "全部大小")

    var lastPageDataMap: HashMap<String, String>? = null

    private val repository = SubjectRepositoryFactory.createListRepo(subjectData.subjectType)

    override fun provideDataObservable(page: Int): Observable<List<GameEntity>>? = null

    override fun provideDataSingle(page: Int): Single<MutableList<GameEntity>> {
        return repository.getColumn(
            subjectData.subjectId,
            page,
            subjectData.sort,
            subjectData.filter.ifEmpty { "type:全部" },
            AdHelper.getIdfaString(),
            columnCollectionId,
            -1,
            false
        )
    }

    override fun mergeResultLiveData() {
        mResultLiveData.addSource(mListLiveData) {
            ExposureUtils.updateExposureInfo(it, subjectId = subjectData.subjectId)

            val gameSubjectData = subjectData.toGameSubjectData()
            val useUpdateTagStyle = subjectData.tagType == "update"

            it.forEach { game ->
                game.isAdData = subjectData.isAdData
                game.subjectData = gameSubjectData
                if (useUpdateTagStyle) {
                    game.tagStyle.clear()
                    game.tagStyle.add(
                        TagStyleEntity(
                            id = "local_generated",
                            name = TimeUtils.getFormatTime(game.updateTime, "MM-dd") + " 更新",
                            color = "1383EB",
                            background = "E8F3FF",
                            column = "1383EB"
                        )
                    )
                }
                game.subPageCode = ExposureConstants.SUBJECT
                game.subPageId = subjectData.subjectId
            }
            mResultLiveData.postValue(it)
        }
    }

    private fun updateSubjectSettingBeforeInitialLoad() {
        // 无论是否加载成功都回落到普通的专题列表加载
        repository
            .getColumnSettings(subjectData.subjectId)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Response<SubjectSettingEntity>() {
                override fun onResponse(response: SubjectSettingEntity?) {
                    super.onResponse(response)
                    subjectData.requireUpdateSetting = false
                    subjectData.tagType = response?.tag
                    subjectData.isOrder = response?.order
                    subjectData.briefStyle = response?.briefStyle ?: ""

                    loadData()
                }

                override fun onFailure(e: HttpException?) {
                    super.onFailure(e)
                    loadData()
                }
            })
    }

    override fun load(loadType: LoadType) {
        if (loadType == LoadType.REFRESH) {
            initLoadParams()
        } else if (loadType == LoadType.RETRY) {
            mLoadStatusLiveData.value = LoadStatus.LIST_LOADED
        }

        if (subjectData.requireUpdateSetting && loadType == LoadType.REFRESH) {
            updateSubjectSettingBeforeInitialLoad()
        } else {
            loadData()
        }
    }

    class Factory(
        private val mApplication: Application,
        private val subjectData: SubjectData,
        private val pageLocation: PageLocation,
        private val exposureSourceList: List<ExposureSource>? = null,
        private val columnCollectionId: String? = null
    ) : ViewModelProvider.NewInstanceFactory() {
        override fun <T : ViewModel> create(modelClass: Class<T>): T {
            return SubjectListViewModel(mApplication, subjectData, pageLocation, exposureSourceList, columnCollectionId) as T
        }
    }

}