package com.adealink.weparty.room.list.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.room.datasource.remote.RoomHttpService
import com.adealink.weparty.room.list.data.RoomListItemData
import com.adealink.weparty.room.list.data.RoomListReq
import com.adealink.weparty.util.PageHandler
import kotlinx.coroutines.launch

class RoomListViewModel : BaseViewModel() {

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

    val listResultSet = mutableSetOf<String>()
    val roomItemListLD = ExtMutableLiveData<List<RoomListItemData>>()
    val listRltLD = ExtMutableLiveData<Rlt<Any>>()
    private val roomItemList = mutableListOf<RoomListItemData>()
    private val pageHandler = PageHandler()
    private var roomTypes: List<Int>? = null
    fun load(roomTypes: List<Int>?) {
        pageHandler.reset()
        this.roomTypes = roomTypes
        listResultSet.clear()
        roomItemList.clear()
        loadMore(roomTypes)
    }

    fun reload() {
        load(roomTypes)
    }

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

    fun loadMore(roomTypes: List<Int>? = this@RoomListViewModel.roomTypes) {
        if (pageHandler.isEnd) {
            listRltLD.send(Rlt.Failed(NoMoreDataError()))
            return
        }
        viewModelScope.launch {
            if (roomTypes.isNullOrEmpty()) {
                listRltLD.send(Rlt.Success(Any()))
                roomItemListLD.send(emptyList())
                return@launch
            }
            val rlt = roomHttpService.roomList(
                RoomListReq(
                    roomTypes = roomTypes,
                    page = PageReq(size = pageHandler.pageSize, next = pageHandler.currentPage)
                )
            )
            when (rlt) {
                is Rlt.Failed -> {
                    listRltLD.send(rlt)
                }

                is Rlt.Success -> {
                    pageHandler.nextPage(rlt.data.data?.next)

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

                    val nextItemList = nextList.map {
                        RoomListItemData(it)
                    }
                    listResultSet.addAll(nextList.map { it.roomId })
                    roomItemList.addAll(nextItemList)
                    listRltLD.send(rlt)
                    roomItemListLD.send(roomItemList)
                }
            }
        }
    }

}