package com.adealink.weparty.room.chat

import android.os.Bundle
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.adealink.frame.base.Rlt
import com.adealink.frame.ext.isViewBindingValid
import com.adealink.frame.mvvm.view.viewBinding
import com.adealink.frame.router.Router
import com.adealink.weparty.commonui.BaseFragment
import com.adealink.weparty.commonui.recycleview.diffutil.BaseListDiffUtil
import com.adealink.weparty.commonui.toast.util.showToast
import com.adealink.weparty.commonui.widget.BottomDialogFragment
import com.adealink.weparty.module.profile.data.UserInfo
import com.adealink.weparty.module.room.Room
import com.adealink.weparty.module.room.chat.data.Message
import com.adealink.weparty.module.room.chat.data.ROOM_MESSAGE_ENTER_ROOM
import com.adealink.weparty.module.room.chat.livemessage.LiveMessageAdapter
import com.adealink.weparty.module.room.chat.livemessage.LiveMessageRecyclerHelper
import com.adealink.weparty.module.room.listener.IMemberInfoListener
import com.adealink.weparty.room.R
import com.adealink.weparty.room.chat.adapter.EnterRoomMessageViewBinder
import com.adealink.weparty.room.chat.adapter.SendGiftMessageViewBinder
import com.adealink.weparty.room.chat.adapter.TextMessageViewBinder
import com.adealink.weparty.room.chat.listener.IMessageOperaListener
import com.adealink.weparty.room.chat.viewmodel.ChatMessageViewModel
import com.adealink.weparty.room.databinding.FragmentChatMessageBinding
import com.adealink.weparty.room.gift.viewmodel.RoomGiftViewModel
import com.adealink.weparty.room.member.viewmodel.RoomMemberViewModel
import com.adealink.weparty.room.viewmodel.RoomViewModelFactory
import io.trtc.tuikit.atomicxcore.api.barrage.Barrage

class ChatMessageFragment : BaseFragment(R.layout.fragment_chat_message),
    IMessageOperaListener,
    IMemberInfoListener {

    private val binding by viewBinding(FragmentChatMessageBinding::bind)
    private var adapter: LiveMessageAdapter<Message>? = null
    private var liveMessageRecyclerHelper: LiveMessageRecyclerHelper<Message>? = null
    private lateinit var layoutManager: LinearLayoutManager

    private val chatMessageViewModel by activityViewModels<ChatMessageViewModel> { RoomViewModelFactory() }

    private val roomGiftViewModel by activityViewModels<RoomGiftViewModel> { RoomViewModelFactory() }
    private val memberViewModel by activityViewModels<RoomMemberViewModel> { RoomViewModelFactory() }

    override fun initViews() {
        layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
        binding.messageRv.layoutManager = layoutManager
        binding.messageRv.itemAnimator = DefaultItemAnimator()
        context?.let { ctx ->
            val helper = LiveMessageRecyclerHelper<Message>(ctx).apply {
                setRecyclerView(binding.messageRv)
                messageRecyclerHelperListener = object : LiveMessageRecyclerHelper.LiveMessageRecyclerHelperListener {
                    override fun unreadMessageCountUpdate(unreadCount: Long) {
                    }

                    override fun onScrollToBottom() {
                    }
                }
            }
            adapter = LiveMessageAdapter(helper, BaseListDiffUtil()).also {
                it.register(TextMessageViewBinder(this@ChatMessageFragment, this@ChatMessageFragment, this@ChatMessageFragment))
                it.register(EnterRoomMessageViewBinder(this@ChatMessageFragment, this@ChatMessageFragment))
                it.register(SendGiftMessageViewBinder(this@ChatMessageFragment, this@ChatMessageFragment))
            }
            liveMessageRecyclerHelper = helper
        }
        binding.messageRv.adapter = adapter
    }

    override fun observeViewModel() {
        super.observeViewModel()
        roomGiftViewModel
        chatMessageViewModel.messagesLD.observe(viewLifecycleOwner) { messages ->
            adapter?.submitList(messages)
        }
        chatMessageViewModel.sendTextMessageResultLD.observeWithoutCache(viewLifecycleOwner) { rlt ->
            when (rlt) {
                is Rlt.Failed -> {
                    showToast(rlt)
                }

                is Rlt.Success<*> -> {
                    //Ntd.
                }
            }
        }
        memberViewModel.audienceJoinedLD.observe(viewLifecycleOwner) {
            onAudienceJoined(it)
        }
    }

    override fun getMemberInfo(
        uid: String,
        callback: (UserInfo?) -> Unit
    ) {
        if (!isViewBindingValid()) {
            callback.invoke(null)
            return
        }
        memberViewModel.getRoomMemberInfo(uid).observe(viewLifecycleOwner) {
            callback(if (it is Rlt.Success) it.data else null)
        }
    }

    override fun getMembersInfo(
        uidSet: Set<String>,
        callback: (Map<String, UserInfo>) -> Unit
    ) {
        if (!isViewBindingValid()) {
            callback.invoke(emptyMap())
            return
        }
        memberViewModel.getRoomMembersInfo(uidSet).observe(viewLifecycleOwner) {
            callback(if (it is Rlt.Success) it.data else emptyMap())
        }
    }

    override fun onAvatarClick(uid: String) {
        Router.getRouterInstance<BottomDialogFragment>(Room.RoomMemberInfo.PATH)?.apply {
            arguments = Bundle().apply {
                putString(Room.Common.EXTRA_UID, uid)
            }
        }?.show(childFragmentManager)
    }

    private fun onAudienceJoined(userInfo: UserInfo) {
        chatMessageViewModel.sendLocalMessage(
            Barrage().apply {
                businessID = ROOM_MESSAGE_ENTER_ROOM
                sender.apply {
                    userID = userInfo.uid
                    userName = userInfo.nickName ?: userInfo.uid
                    avatarURL = userInfo.avatar ?: ""
                }
            }
        )
    }
}