package com.adealink.weparty.im.list

import android.view.View
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.adealink.frame.base.Rlt
import com.adealink.frame.base.fastLazy
import com.adealink.frame.ext.isViewBindingValid
import com.adealink.frame.mvvm.view.viewBinding
import com.adealink.frame.router.Router
import com.adealink.frame.router.annotation.RouterUri
import com.adealink.weparty.commonui.BaseFragment
import com.adealink.weparty.commonui.ext.dp
import com.adealink.weparty.commonui.ext.isSuccess
import com.adealink.weparty.commonui.recycleview.itemdecoration.VerticalSpaceItemDecoration
import com.adealink.weparty.im.R
import com.adealink.weparty.im.comp.SessionPermissionComp
import com.adealink.weparty.im.constant.OFFICIAL_CONVERSATION_ID
import com.adealink.weparty.im.constant.OFFICIAL_UID
import com.adealink.weparty.im.databinding.FragmentSessionListBinding
import com.adealink.weparty.im.list.adapter.SessionListAdapter
import com.adealink.weparty.im.list.adapter.viewbinder.OfficialListItemViewBinder
import com.adealink.weparty.im.list.adapter.viewbinder.SessionListItemViewBinder
import com.adealink.weparty.im.list.viewmodel.SessionListViewModel
import com.adealink.weparty.im.listener.IUserInfoListener
import com.adealink.weparty.im.manager.login.imLoginManager
import com.adealink.weparty.im.viewmodel.IMViewModelFactory
import com.adealink.weparty.module.im.IM
import com.adealink.weparty.module.profile.Profile
import com.adealink.weparty.module.profile.ProfileModule
import com.adealink.weparty.module.profile.data.UserInfo
import com.tencent.imsdk.v2.V2TIMConversation
import com.tencent.qcloud.tuikit.tuiconversation.bean.ConversationInfo
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.interfaces.OnConversationAdapterListener
import com.tencent.qcloud.tuikit.tuiconversation.minimalistui.util.TUIConversationUtils
import com.tencent.qcloud.tuikit.tuiconversation.presenter.ConversationPresenter


@RouterUri(
    path = [IM.SessionList.PATH],
    desc = "IM会话列表"
)
class SessionListFragment : BaseFragment(R.layout.fragment_session_list),
    OnConversationAdapterListener,
    IUserInfoListener {

    private val binding by viewBinding(FragmentSessionListBinding::bind)
    private val presenter: ConversationPresenter by fastLazy { ConversationPresenter() }
    private val sessionAdapter: SessionListAdapter by fastLazy { SessionListAdapter() }
    private val sessionListViewModel by activityViewModels<SessionListViewModel> { IMViewModelFactory() }
    private val profileViewModel by fastLazy { ProfileModule.getProfileViewModel(this) }

    override fun initViews() {
        super.initViews()
        initSessionList()
    }

    override fun initComponents() {
        super.initComponents()
        SessionPermissionComp(this, binding.vOpenNotification).attach()
    }

    private fun initSessionList() {
        val lastItemBottom = arguments?.getInt(IM.SessionList.EXTRA_LAST_ITEM_BOTTOM) ?: 0
        binding.conversationLayout.layoutManager =
            LinearLayoutManager(context, RecyclerView.VERTICAL, false)
        binding.conversationLayout.addItemDecoration(
            VerticalSpaceItemDecoration(10.dp(), lastSpaceHeight = lastItemBottom)
        )

        sessionAdapter.register(OfficialListItemViewBinder(this))
        sessionAdapter.register(
            SessionListItemViewBinder(
                this,
                this,
                { uid ->
                    onAvatarClick(uid)
                }, this
            )
        )
        sessionAdapter.mOnConversationAdapterListener = this

        presenter.setAdapter(sessionAdapter)
        presenter.setConversationListener()
        presenter.setShowType(ConversationPresenter.SHOW_TYPE_CONVERSATION_LIST_WITH_FOLD)
        binding.conversationLayout.adapter = sessionAdapter
        binding.conversationLayout.setPresenter(presenter)
        sessionListViewModel.setPresenter(presenter)
        sessionListViewModel.setAdapter(sessionAdapter)
    }

    override fun onResume() {
        super.onResume()
        imLoginManager.checkLogin()
        presenter.loadConversation(OFFICIAL_CONVERSATION_ID)
        binding.conversationLayout.loadConversation()
        binding.conversationLayout.loadMarkedConversation()
    }

    override fun onDestroyView() {
        super.onDestroyView()
        presenter.destroy()
    }

    override fun onItemClick(
        view: View?,
        viewType: Int,
        conversationInfo: ConversationInfo?
    ) {
        conversationInfo ?: return
        if (conversationInfo.conversation?.userID == OFFICIAL_UID) {
            goOfficialSession(conversationInfo)
            return
        }

        activity?.let { act ->
            Router.build(act, IM.Session.PATH)
                .putExtra(
                    IM.Session.EXTRA_CHAT_TYPE,
                    if (conversationInfo.isGroup) V2TIMConversation.V2TIM_GROUP else V2TIMConversation.V2TIM_C2C
                )
                .putExtra(IM.Session.EXTRA_CHAT_ID, conversationInfo.id)
                .putExtra(IM.Session.EXTRA_CHAT_NAME, conversationInfo.title)
                .putExtra(IM.Session.EXTRA_CHAT_DRAFT_TEXT, conversationInfo.draft?.draftText)
                .putExtra(IM.Session.EXTRA_CHAT_DRAFT_TIME, conversationInfo.draft?.draftTime)
                .start()
        }
    }

    private fun goOfficialSession(conversationInfo: ConversationInfo) {
        activity?.let { act ->
            Router.build(act, IM.OfficialSession.PATH)
                .putExtra(
                    IM.Session.EXTRA_CHAT_TYPE,
                    if (conversationInfo.isGroup) V2TIMConversation.V2TIM_GROUP else V2TIMConversation.V2TIM_C2C
                )
                .putExtra(IM.Session.EXTRA_CHAT_ID, conversationInfo.id)
                .putExtra(IM.Session.EXTRA_CHAT_NAME, conversationInfo.title)
                .putExtra(IM.Session.EXTRA_CHAT_DRAFT_TEXT, conversationInfo.draft?.draftText)
                .putExtra(IM.Session.EXTRA_CHAT_DRAFT_TIME, conversationInfo.draft?.draftTime)
                .start()
        }
    }

    override fun onItemLongClick(
        view: View?,
        conversationInfo: ConversationInfo?
    ) {
        TUIConversationUtils.startChatActivity(conversationInfo)
    }

    override fun onConversationChanged(dataSource: List<ConversationInfo?>?) {
        sessionListViewModel.loadConversationUserInfo(dataSource)
    }

    //标记为"未读"(无此功能)
    override fun onMarkConversationUnread(
        view: View?,
        conversationInfo: ConversationInfo?,
        markUnread: Boolean
    ) {
    }

    //标记为"隐藏"(无此功能)
    override fun onMarkConversationHidden(
        view: View?,
        conversationInfo: ConversationInfo?
    ) {
    }

    //点击更多(无此功能)
    override fun onClickMoreView(
        view: View?,
        conversationInfo: ConversationInfo?
    ) {

    }

    //滑动(无此功能)
    override fun onSwipeConversationChanged(conversationInfo: ConversationInfo?) {

    }

    private fun onAvatarClick(uid: String) {
        val act = activity ?: return
        Router.build(act, Profile.UserProfile.PATH)
            .putExtra(Profile.Common.EXTRA_UID, uid)
            .start()
    }

    override fun getUserInfo(uid: String, callback: (UserInfo?) -> Unit) {
        if (!isViewBindingValid()) {
            callback.invoke(null)
            return
        }
        profileViewModel?.pullUserInfoBy(uid, true)?.observe(viewLifecycleOwner) { rlt ->
            when (rlt) {
                is Rlt.Failed -> {
                    callback(null)
                }

                is Rlt.Success -> {
                    val userInfo = rlt.data
                    callback(userInfo)

                    //加载备注
                    profileViewModel?.pullUserNoteBy(uid, true)
                        ?.observe(viewLifecycleOwner) { noteRlt ->
                            when (noteRlt) {
                                is Rlt.Failed -> {

                                }

                                is Rlt.Success -> {
                                    userInfo.userNote = noteRlt.data
                                    callback(userInfo)
                                }
                            }
                        }
                }
            }

        }
    }

}