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.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.DynamicCommentListReq
import com.adealink.weparty.profile.dynamic.fragment.data.BaseDynamicDetailItem
import com.adealink.weparty.profile.dynamic.fragment.data.DynamicDetailCommentItem
import com.adealink.weparty.util.PageHandler
import kotlinx.coroutines.launch

class DynamicCommentViewModel : BaseViewModel() {

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

    private var dynamicId: String? = null
    private var commentTotal: Long = 0
    private var commentList = mutableListOf<DynamicCommentData>()

    val totalCommentLD = ExtMutableLiveData<Long>()
    private var commentIdSet = mutableSetOf<String>()
    val commentListLD = ExtMutableLiveData<List<BaseDynamicDetailItem>>()
    val commentListRltLD = ExtMutableLiveData<Rlt<Any>>()
    private val pageHandler = PageHandler()

    private var newCommentCount = 0

    fun loadDynamicDetail(id: String?) {
        viewModelScope.launch {
            commentList.clear()
            commentIdSet.clear()
            pageHandler.reset()
            newCommentCount = 0
            this@DynamicCommentViewModel.dynamicId = id
            loadMore()
        }
    }

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

    fun loadMore() {
        if (pageHandler.isEnd) {
            commentListRltLD.send(Rlt.Failed(NoMoreDataError()))
            return
        }
        viewModelScope.launch {
            val dynamicId = this@DynamicCommentViewModel.dynamicId
            if (dynamicId.isNullOrEmpty()) {
                return@launch
            }
            val rlt = dynamicHttpService.dynamicCommentList(
                DynamicCommentListReq(
                    dynamicId,
                    page = PageReq(size = pageHandler.pageSize, next = pageHandler.currentPage)
                )
            )
            when (rlt) {
                is Rlt.Failed -> {
                    commentListRltLD.send(rlt)
                }

                is Rlt.Success -> {
                    pageHandler.nextPage(rlt.data.data?.next)
                    commentTotal = rlt.data.data?.total ?: 0

                    val nextList = rlt.data.data?.list?.filter {
                        !commentIdSet.contains(it.id)
                    } ?: emptyList()
                    commentIdSet.addAll(nextList.map { it.id })
                    commentList.addAll(nextList)
                    commentListRltLD.send(rlt)
                    notifyItemChanged()
                }
            }
        }
    }

    private fun notifyItemChanged() {
        viewModelScope.launch {
            val commentTotalCount = newCommentCount + commentTotal

            if (commentList.isEmpty()) {
                commentListLD.send(emptyList())
                totalCommentLD.send(commentTotalCount)
                return@launch
            }
            val itemList = mutableListOf<BaseDynamicDetailItem>()
//            itemList.add(
//                DynamicDetailCommentTitleItem(max(commentTotal, commentList.size.toLong()))
//            )
            itemList.addAll(
                commentList.map {
                    DynamicDetailCommentItem(it)
                }
            )
            commentListLD.send(itemList)
            totalCommentLD.send(commentTotalCount)
        }
    }

    fun onNewCommentAdd(comment: DynamicCommentData) {
        if (commentIdSet.contains(comment.id)) {
            return
        }
        commentIdSet.add(comment.id)
        commentList.add(0, comment)
        newCommentCount++
        notifyItemChanged()
    }

}