package com.adealink.weparty.room.sdk.controller.impl

import android.os.Handler
import com.adealink.frame.base.CommonDataNullError
import com.adealink.frame.base.Rlt
import com.adealink.frame.coroutine.dispatcher.Dispatcher
import com.adealink.frame.log.Log
import com.adealink.frame.room.data.FlowStateInfo
import com.adealink.frame.room.data.LeaveRoomReason
import com.adealink.frame.room.data.RoomInfoSizeError
import com.adealink.frame.room.data.TAG_ROOM_ATTR
import com.adealink.weparty.commonui.toast.util.showToast
import com.adealink.weparty.module.room.data.RoomInfo
import com.adealink.weparty.room.R
import com.adealink.weparty.room.data.ROOM_META_AUTO_MIC_MUTE
import com.adealink.weparty.room.data.ROOM_META_HOST_LIST
import com.adealink.weparty.room.data.ROOM_META_MIC_APPLY_NUMBER
import com.adealink.weparty.room.data.ROOM_META_ROOM_TYPE
import com.adealink.weparty.room.data.isAutoMuteMic
import com.adealink.weparty.room.data.isSupportRoomType
import com.adealink.weparty.room.sdk.context.IRoomContext
import com.adealink.weparty.room.sdk.controller.BaseController
import com.adealink.weparty.room.sdk.controller.IAttrController
import com.adealink.weparty.room.sdk.listener.IAttrListener
import com.adealink.weparty.room.sdk.listener.ISeatListener
import com.adealink.weparty.room.sdk.service.roomService
import io.trtc.tuikit.atomicxcore.api.live.LiveListStore
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

class AttrController(override val ctx: IRoomContext, serialHandler: Handler) :
    BaseController<IAttrListener>(ctx, serialHandler),
    IAttrController<IAttrListener>,
    ISeatListener {

    private var myRoomInfo: RoomInfo? = null

    private var _autoForbidAudio = MutableStateFlow(false)
    override val autoForbidAudio: StateFlow<Boolean> = _autoForbidAudio.asStateFlow()

    private var attrJob: Job? = null

    private suspend fun updateMyRoomInfo(roomInfo: RoomInfo?) {
        withContext(this.coroutineContext) {
            myRoomInfo = roomInfo
        }
    }

    override fun onRoomIn(flowStateInfo: FlowStateInfo) {
        roomService.seatController.addListener(this)
        attrJob = launch {
            launch {
                LiveListStore.shared().liveState.currentLive.map {
                    it.isAutoMuteMic()
                }.distinctUntilChanged().collect {
                    _autoForbidAudio.update { it }
                }
            }
            launch {
                LiveListStore.shared().liveState.currentLive.map {
                    it.isSupportRoomType()
                }.distinctUntilChanged().collect { support ->
                    if (!support) {
                        CoroutineScope(Dispatcher.UI).launch {
                            showToast(R.string.room_unsupported_room_type)
                            roomService.joinController.leaveRoom(LeaveRoomReason.UNSUPPORTED_ROOM_TYPE, true)
                        }
                    }
                }
            }
        }
    }

    override fun onRoomLeaved(flowStateInfo: FlowStateInfo) {
        roomService.seatController.removeListener(this)
        attrJob?.cancel()
    }

    override suspend fun getRoomInfo(
        roomIds: List<Long>,
        from: Long?,
        needRoomOnlineInfo: Boolean,
        getRoomOwnerFamily: Boolean
    ): Rlt<List<RoomInfo>> {
        return Rlt.Success(emptyList())
//        return when (val result =
//            roomHttpService.getRoomInfo(
//                GetRoomsInfoReq(
//                    roomIds,
//                    needRoomOnlineInfo = needRoomOnlineInfo,
//                    getRoomOwnerFamily = getRoomOwnerFamily
//                )
//            )) {
//            is Rlt.Success -> {
//                Rlt.Success(result.data.data?.roomInfoList ?: emptyList())
//            }
//
//            is Rlt.Failed -> result
//        }
    }

    override suspend fun getRoomInfo(roomId: Long): Rlt<RoomInfo> {
        return when (val result = getRoomInfo(listOf(roomId), getRoomOwnerFamily = true)) {
            is Rlt.Success -> {
                val roomInfoList = result.data
                if (roomInfoList.isEmpty().not()) {
                    Rlt.Success(roomInfoList[0])
                } else {
                    Rlt.Failed(RoomInfoSizeError())
                }
            }

            is Rlt.Failed -> {
                result.apply { error.data = roomId }
            }
        }.apply {
            Log.logRltD(TAG_ROOM_ATTR, "getRoomInfo, roomId:${roomId}", this)
        }
    }

    private suspend fun getMyRoomInfoFromNet(): Rlt<RoomInfo> {
//        return when (val result = roomHttpService.getMyRoomInfo()) {
//            is Rlt.Success -> {
//                if (result.data.data == null) {
//                    return Rlt.Failed(CommonDataNullError())
//                }
//                Rlt.Success(result.data.data!!.roomInfo)
//            }
//
//            is Rlt.Failed -> {
//                return if (result.error.serverCode == ServerCode.USER_NO_ROOM.code) {
//                    Rlt.Failed(RoomNoExistError())
//                } else {
//                    result
//                }
//            }
//        }.apply {
//            Log.logRltD(TAG_ROOM_ATTR, "getMyRoomInfoFromNet", this)
//        }
        return Rlt.Failed(CommonDataNullError())
    }

    override fun getNecessaryRoomConfig(roomId: String) {
        launch {
            LiveListStore.shared().queryMetaData(
                listOf(
                    ROOM_META_HOST_LIST,
                    ROOM_META_MIC_APPLY_NUMBER,
                    ROOM_META_AUTO_MIC_MUTE,
                    ROOM_META_ROOM_TYPE
                ), null
            )
        }
    }

    override fun onClear() {
        super.onClear()
        launch {
            updateMyRoomInfo(null)
        }
    }
}