package com.adealink.weparty.profile.search.viewmodel

import com.adealink.frame.base.Rlt
import com.adealink.frame.mvvm.livedata.ExtMutableLiveData
import com.adealink.frame.mvvm.viewmodel.BaseViewModel
import com.adealink.frame.network.data.PageReq
import com.adealink.weparty.App
import com.adealink.weparty.module.profile.ProfileModule
import com.adealink.weparty.network.data.NoMoreDataError
import com.adealink.weparty.profile.datasource.remote.SearchHttpService
import com.adealink.weparty.profile.search.data.SearchUserReq
import com.adealink.weparty.profile.search.data.SearchUserResultItemData
import com.adealink.weparty.util.PageHandler
import kotlinx.coroutines.launch

class SearchUserViewModel : BaseViewModel() {

    private val searchHttpService by lazy {
        App.instance.networkService.getHttpService(SearchHttpService::class.java)
    }

    val searchResultSet = mutableSetOf<String>()
    val searchResultLD = ExtMutableLiveData<List<SearchUserResultItemData>>()
    val searchRltLD = ExtMutableLiveData<Rlt<Any>>()
    private val searchResultList = mutableListOf<SearchUserResultItemData>()
    private val pageHandler = PageHandler()
    private var keyword: String? = null
    fun search(keyword: String?) {
        pageHandler.reset()
        this.keyword = keyword
        searchResultSet.clear()
        searchResultList.clear()
        searchMore(keyword)
    }

    fun reSearch() {
        search(keyword)
    }

    fun hasMoreData(): Boolean {
        return !pageHandler.isEnd
    }

    fun searchMore(keyword: String? = this@SearchUserViewModel.keyword) {
        if (pageHandler.isEnd) {
            searchRltLD.send(Rlt.Failed(NoMoreDataError()))
            return
        }
        viewModelScope.launch {
            if (keyword.isNullOrEmpty()) {
                searchRltLD.send(Rlt.Success(Any()))
                searchResultLD.send(emptyList())
                return@launch
            }
            val rlt = searchHttpService.searchUser(
                SearchUserReq(
                    keyword = keyword,
                    page = PageReq(size = pageHandler.pageSize, next = pageHandler.currentPage)
                )
            )
            when (rlt) {
                is Rlt.Failed -> {
                    if (keyword != this@SearchUserViewModel.keyword) {
                        return@launch
                    }
                    searchRltLD.send(rlt)
                }

                is Rlt.Success -> {
                    if (keyword != this@SearchUserViewModel.keyword) {
                        return@launch
                    }
                    pageHandler.nextPage(rlt.data.data?.next)

                    val nextList = rlt.data.data?.list?.filter {
                        !searchResultSet.contains(it.uid)
                    } ?: emptyList()

                    val nextItemList = nextList.map {
                        it.online?.let { online ->
                            ProfileModule.updateUserOnline(it.uid, online)
                        }

                        SearchUserResultItemData(it)
                    }
                    searchResultSet.addAll(nextList.map { it.uid })
                    searchResultList.addAll(nextItemList)
                    searchRltLD.send(rlt)
                    searchResultLD.send(searchResultList)
                }
            }
        }
    }

    fun notifyFollowChanged(uid: String, follow: Boolean) {
        viewModelScope.launch {
            searchResultList.find { it.data.uid == uid }?.data?.follow = follow
            searchResultLD.send(searchResultList)
        }
    }
}