package com.gh.gamecenter.search.viewmodel

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.gh.gamecenter.SearchActivity
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.clearHtmlFormatCompletely
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.home.custom.model.CustomPageData
import com.gh.gamecenter.livedata.Event
import com.gh.gamecenter.search.SearchGameListRepository
import io.reactivex.disposables.CompositeDisposable

class SearchGameListViewModel : ViewModel() {

    private val repository = SearchGameListRepository.newInstance()

    private val compositeDisposable = CompositeDisposable()

    private var page = 1

    private var key = ""
    private var type = ""
    private var location = ""

    private val _loadStatus = MutableLiveData<LoadStatus>()
    val loadStatus: LiveData<LoadStatus> = _loadStatus

    private val _dataList = MutableLiveData<List<CustomPageData.LinkColumnCollection.CustomSubjectEntity>?>()
    val dataList: LiveData<List<CustomPageData.LinkColumnCollection.CustomSubjectEntity>?> = _dataList

    fun loadFirstData(key: String, type: String, location: String) {
        this.key = key
        this.type = type
        this.location = location
        page = 1
        _loadStatus.value = LoadStatus.INIT_LOADING
        searchGameList()
    }

    fun onLoadMore() {
        page++
        _loadStatus.value = LoadStatus.LIST_LOADING
        searchGameList()
    }

    fun retry() {
        _loadStatus.value = if (page == 1) {
            LoadStatus.INIT_LOADING
        } else {
            LoadStatus.LIST_LOADED
        }
        searchGameList()
    }

    private fun searchGameList() {
        repository.searchGameList(key, page)
            .compose(singleToMain())
            .subscribe(object : BiResponse<List<CustomPageData.LinkColumnCollection.CustomSubjectEntity>>() {
                override fun onSuccess(data: List<CustomPageData.LinkColumnCollection.CustomSubjectEntity>) {
                    if (page == 1) {
                        _dataList.value = data
                        _loadStatus.value = when {
                            data.isEmpty() -> LoadStatus.INIT_EMPTY
                            data.size < 10 -> LoadStatus.LIST_OVER
                            else -> LoadStatus.INIT_LOADED
                        }
                        SensorsBridge.trackGameCollectSearchResultReturn(
                            GlobalActivityManager.getCurrentPageEntity().pageId,
                            GlobalActivityManager.getCurrentPageEntity().pageName,
                            location,
                            key,
                            SearchActivity.toTrackSearchType(type),
                            data.isNotEmpty()
                        )
                    } else {
                        addData(data)
                        _loadStatus.value = if (data.size < 10) {
                            LoadStatus.LIST_OVER
                        } else {
                            LoadStatus.LIST_LOADED
                        }
                    }

                }

                override fun onFailure(exception: Exception) {
                    _loadStatus.value = if (page == 1) {
                        LoadStatus.INIT_FAILED
                    } else {
                        LoadStatus.LIST_FAILED
                    }
                }
            }).let(compositeDisposable::add)
    }

    private fun addData(newData: List<CustomPageData.LinkColumnCollection.CustomSubjectEntity>) {
        val oldData = dataList.value
        _dataList.value = if (oldData == null) {
            newData
        } else {
            oldData + newData
        }
    }

    private val _gameDetailDestination = MutableLiveData<Event<String>>()
    val gameDetailDestination: LiveData<Event<String>> = _gameDetailDestination
    fun navigateToGameDetailPage(
        gameId: String,
        position: Int,
        collection: CustomPageData.LinkColumnCollection.CustomSubjectEntity
    ) {
        trackGameCollectSearchResultClick(position, collection)
        _gameDetailDestination.value = Event(gameId)
    }

    private val _homeDestination = MutableLiveData<Event<String>>()
    val homeDestination: LiveData<Event<String>> = _homeDestination
    fun navigateToHomePage(
        userId: String,
        position: Int,
        collection: CustomPageData.LinkColumnCollection.CustomSubjectEntity
    ) {
        trackGameCollectSearchResultClick(position, collection)
        _homeDestination.value = Event(userId)
    }

    private val _gameCollectionDetailDestination = MutableLiveData<Event<Pair<String, List<ExposureSource>>>>()
    val gameCollectionDetailDestination: LiveData<Event<Pair<String, List<ExposureSource>>>> =
        _gameCollectionDetailDestination

    fun navigateGameCollectionDetailPage(
        position: Int,
        collection: CustomPageData.LinkColumnCollection.CustomSubjectEntity,
        exposureSourceList: List<ExposureSource>
    ) {
        trackGameCollectSearchResultClick(position, collection)
        _gameCollectionDetailDestination.value = Event(collection.id to exposureSourceList)
    }

    private fun trackGameCollectSearchResultClick(
        position: Int,
        collection: CustomPageData.LinkColumnCollection.CustomSubjectEntity
    ) {
        SensorsBridge.trackGameCollectSearchResultClick(
            GlobalActivityManager.getCurrentPageEntity().pageId,
            GlobalActivityManager.getCurrentPageEntity().pageName,
            key,
            SearchActivity.toTrackSearchType(type),
            location,
            collection.id,
            collection.title.clearHtmlFormatCompletely(),
            position
        )
    }
}