package com.adealink.weparty.profile.relation.viewmodel

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
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.weparty.App
import com.adealink.weparty.module.profile.data.FollowStatus
import com.adealink.weparty.module.profile.viewmodel.IFollowViewModel
import com.adealink.weparty.profile.datasource.remote.FollowHttpService
import com.adealink.weparty.profile.relation.data.FansItemData
import com.adealink.weparty.profile.relation.data.FansListReq
import com.adealink.weparty.profile.relation.data.FollowItemData
import com.adealink.weparty.profile.relation.data.FollowListReq
import com.adealink.weparty.profile.relation.data.FollowReq
import com.adealink.weparty.profile.relation.data.FollowStatusReq
import com.adealink.weparty.util.PageHandler
import kotlinx.coroutines.launch

class FollowViewModel : BaseViewModel(), IFollowViewModel {

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

    private val followStatusMap = mutableMapOf<String, FollowStatus>()
    override val isFollowLD = ExtMutableLiveData<Map<String, FollowStatus>>()
    override fun isFollow(uid: String): LiveData<Rlt<FollowStatus>> {
        val liveData = OnceMutableLiveData<Rlt<FollowStatus>>()
        viewModelScope.launch {
            val rlt = followHttpService.isFollow(FollowStatusReq(listOf(uid)))
            when (rlt) {
                is Rlt.Failed -> {
                    liveData.send(rlt)
                }

                is Rlt.Success -> {
                    val followStatus =
                        FollowStatus.map(rlt.data.data?.list?.find { it.uid == uid }?.followStatus)
                    followStatusMap[uid] = followStatus
                    isFollowLD.send(followStatusMap)
                    liveData.send(Rlt.Success(followStatus))
                }
            }
        }
        return liveData
    }


    override fun isFollow(uids: List<String>): LiveData<Rlt<Map<String, FollowStatus>>> {
        val liveData = OnceMutableLiveData<Rlt<Map<String, FollowStatus>>>()
        viewModelScope.launch {
            val rlt = followHttpService.isFollow(FollowStatusReq(uids.distinct()))
            when (rlt) {
                is Rlt.Failed -> {
                    liveData.send(rlt)
                }

                is Rlt.Success -> {
                    rlt.data.data?.list?.forEach {
                        followStatusMap[it.uid] = FollowStatus.map(it.followStatus)
                    }
                    isFollowLD.send(followStatusMap)
                    liveData.send(Rlt.Success(followStatusMap))
                }
            }
        }
        return liveData
    }

    override fun follow(uid: String): LiveData<Rlt<Any>> {
        val liveData = OnceMutableLiveData<Rlt<Any>>()
        viewModelScope.launch {
            val rlt = followHttpService.follow(FollowReq(uid, true))
            when (rlt) {
                is Rlt.Failed -> {
                    //ntd.
                }

                is Rlt.Success -> {
                    onFollowStatusChanged(uid, true)
                }
            }
            liveData.send(rlt)
        }
        return liveData
    }

    override fun unFollow(uid: String): LiveData<Rlt<Any>> {
        val liveData = OnceMutableLiveData<Rlt<Any>>()
        viewModelScope.launch {
            val rlt = followHttpService.follow(FollowReq(uid, false))
            when (rlt) {
                is Rlt.Failed -> {
                    //ntd.
                }

                is Rlt.Success -> {
                    onFollowStatusChanged(uid, false)
                }
            }
            liveData.send(rlt)
        }
        return liveData
    }


    private fun onFollowStatusChanged(uid: String, follow: Boolean) {
        val currentStatus = followStatusMap[uid]
        val nextStatus = when (currentStatus) {
            FollowStatus.NONE, null -> {
                if (follow) {
                    FollowStatus.FOLLOW
                } else {
                    FollowStatus.NONE
                }
            }

            FollowStatus.EACH_FOLLOW -> {
                if (follow) {
                    FollowStatus.EACH_FOLLOW
                } else {
                    FollowStatus.FANS
                }
            }

            FollowStatus.FANS -> {
                if (follow) {
                    FollowStatus.EACH_FOLLOW
                } else {
                    FollowStatus.FANS
                }
            }

            FollowStatus.FOLLOW -> {
                if (follow) {
                    FollowStatus.FOLLOW
                } else {
                    FollowStatus.NONE
                }
            }
        }
        followStatusMap[uid] = nextStatus
        isFollowLD.send(followStatusMap)
    }


    private val followList = mutableListOf<FollowItemData>()
    private val followUids = mutableSetOf<String>()
    private val followPageHandler = PageHandler()

    val followListRltLD = ExtMutableLiveData<Rlt<Any>>()
    val followListLD = MutableLiveData<List<FollowItemData>>()
    fun pullFollowList() {
        followList.clear()
        followUids.clear()
        followPageHandler.reset()
        loadMoreFollowList()
    }

    fun loadMoreFollowList() {
        viewModelScope.launch {
            val rlt = followHttpService.pullFollow(
                FollowListReq(
                    size = followPageHandler.pageSize,
                    next = followPageHandler.currentPage
                )
            )
            when (rlt) {
                is Rlt.Failed -> {
                    followListRltLD.send(rlt)
                }

                is Rlt.Success -> {
                    followPageHandler.nextPage(rlt.data.data?.next)
                    rlt.data.data?.list?.forEach {
                        if (!followUids.contains(it.uid)) {
                            followList.add(FollowItemData(it))
                            followUids.add(it.uid)
                        }
                    }
                    followListRltLD.send(rlt)
                    followListLD.send(followList)
                }
            }
        }
    }


    private val fansList = mutableListOf<FansItemData>()
    private val fansUids = mutableSetOf<String>()
    private val fansPageHandler = PageHandler()
    val fansListRltLD = ExtMutableLiveData<Rlt<Any>>()
    val fansListLD = MutableLiveData<List<FansItemData>>()
    fun pullFansList() {
        fansList.clear()
        fansUids.clear()
        fansPageHandler.reset()
        loadMoreFansList()
    }

    fun loadMoreFansList() {
        viewModelScope.launch {
            val rlt = followHttpService.pullFans(
                FansListReq(
                    size = fansPageHandler.pageSize,
                    next = fansPageHandler.currentPage
                )
            )
            when (rlt) {
                is Rlt.Failed -> {
                    fansListRltLD.send(rlt)
                }

                is Rlt.Success -> {
                    fansPageHandler.nextPage(rlt.data.data?.next)
                    rlt.data.data?.list?.forEach {
                        if (!fansUids.contains(it.uid)) {
                            fansList.add(FansItemData(it))
                            fansUids.add(it.uid)
                        }
                    }
                    fansListRltLD.send(rlt)
                    fansListLD.send(fansList)
                }
            }
        }
    }
}