package com.adealink.weparty.profile.dynamic.viewmodel

import com.adealink.frame.base.Rlt
import com.adealink.frame.mvvm.livedata.ExtMutableLiveData
import com.adealink.frame.mvvm.livedata.OnceMutableLiveData
import com.adealink.frame.mvvm.viewmodel.BaseViewModel
import com.adealink.frame.network.data.PageReq
import com.adealink.weparty.App
import com.adealink.weparty.network.data.NoMoreDataError
import com.adealink.weparty.profile.datasource.remote.DynamicHttpService
import com.adealink.weparty.profile.dynamic.data.DynamicCommentData
import com.adealink.weparty.profile.dynamic.data.DynamicDetailData
import com.adealink.weparty.profile.dynamic.data.DynamicListReq
import com.adealink.weparty.util.PageHandler
import kotlinx.coroutines.launch

class DynamicListViewModel : BaseViewModel() {

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

    val dynamicListLD = ExtMutableLiveData<List<DynamicDetailData>>()
    val dynamicListRltLD = ExtMutableLiveData<Rlt<Any>>()
    private val dynamicList = mutableListOf<DynamicDetailData>()
    private val dynamicIdSet = mutableSetOf<String>()
    private val pageHandler = PageHandler()
    private var reqUid: String? = null

    fun pullDynamicIfEmpty(uid: String?) {
        if (pageHandler.isEnd || dynamicList.isNotEmpty()) {
            return
        }
        pullDynamic(uid)
    }

    fun pullDynamic(uid: String?) {
        pageHandler.reset()
        dynamicList.clear()
        dynamicIdSet.clear()
        reqUid = uid
        loadMoreDynamic()
    }

    fun reloadDynamic() {
        pullDynamic(reqUid)
    }

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

    fun loadMoreDynamic() {
        if (pageHandler.isEnd) {
            dynamicListRltLD.send(Rlt.Failed(NoMoreDataError()))
            return
        }
        viewModelScope.launch {
            val reqUid = reqUid
            if (reqUid.isNullOrEmpty()) {
                return@launch
            }
            val rlt = dynamicHttpService.dynamicList(
                DynamicListReq(
                    reqUid,
                    page = PageReq(size = pageHandler.pageSize, next = pageHandler.currentPage)
                )
            )
            when (rlt) {
                is Rlt.Failed -> {
                    dynamicListRltLD.send(rlt)
                }

                is Rlt.Success -> {
                    pageHandler.nextPage(rlt.data.data?.next)
                    val newList = rlt.data.data?.list?.filter {
                        !dynamicIdSet.contains(it.id)
                    } ?: emptyList()
                    dynamicIdSet.addAll(newList.map { it.id })
                    dynamicList.addAll(newList)
                    dynamicListRltLD.send(rlt)
                    dynamicListLD.send(dynamicList)
                }
            }
        }
    }

    fun onPublishNewDynamic() {
        viewModelScope.launch {
            val reqUid = reqUid
            if (reqUid.isNullOrEmpty()) {
                return@launch
            }
            val rlt = dynamicHttpService.dynamicList(
                DynamicListReq(
                    reqUid,
                    page = PageReq(size = 1, next = "")
                )
            )
            when (rlt) {
                is Rlt.Failed -> {
                    return@launch
                }

                is Rlt.Success -> {
                    val firstDynamic = rlt.data.data?.list?.firstOrNull() ?: return@launch
                    if (firstDynamic.id == dynamicList.firstOrNull()?.id) {
                        return@launch
                    }
                    dynamicList.add(0, firstDynamic)
                    dynamicIdSet.add(firstDynamic.id)
                    dynamicListLD.send(dynamicList)
                }
            }
        }
    }

    fun onDynamicDelete(dynamicId: String) {
        viewModelScope.launch {
            if (!dynamicIdSet.contains(dynamicId)) {
                return@launch
            }
            dynamicList.indexOfFirst { it.id == dynamicId }.let { index ->
                if (index >= 0) {
                    dynamicIdSet.remove(dynamicId)
                    dynamicList.removeAt(index)
                    dynamicListLD.send(dynamicList)
                }
            }
        }
    }

}