package com.adealink.weparty.room.invite

import android.os.Bundle
import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.adealink.frame.aab.util.getCompatColor
import com.adealink.frame.aab.util.getCompatString
import com.adealink.frame.base.Rlt
import com.adealink.frame.base.fastLazy
import com.adealink.frame.ext.findAndSetSpan
import com.adealink.frame.mvvm.view.viewBinding
import com.adealink.frame.router.Router
import com.adealink.frame.util.onClick
import com.adealink.weparty.commonui.ext.gone
import com.adealink.weparty.commonui.ext.show
import com.adealink.weparty.commonui.recycleview.adapter.MultiTypeListAdapter
import com.adealink.weparty.commonui.toast.util.showFailedToast
import com.adealink.weparty.commonui.widget.BottomDialogFragment
import com.adealink.weparty.module.playmate.data.PlaymateCategoryData
import com.adealink.weparty.module.room.Room
import com.adealink.weparty.room.R
import com.adealink.weparty.room.databinding.DialogRoomInviteMicBinding
import com.adealink.weparty.room.invite.adapter.RoomMemberViewBinder
import com.adealink.weparty.room.invite.data.RoomMemberItemData
import com.adealink.weparty.room.invite.viewmodel.InviteViewModel
import com.adealink.weparty.room.member.RoomPlaymateFilterDialog
import com.scwang.smart.refresh.layout.api.RefreshLayout
import com.scwang.smart.refresh.layout.listener.OnRefreshLoadMoreListener
import com.adealink.weparty.R as APP_R

class InviteMicDialog : BottomDialogFragment(R.layout.dialog_room_invite_mic) {

    private val binding by viewBinding(DialogRoomInviteMicBinding::bind)

    private val listAdapter by fastLazy { MultiTypeListAdapter<RoomMemberItemData>() }

    private val inviteViewModel by viewModels<InviteViewModel>()
    private var enableFilter = false

    private var filterPlaymateCategory: List<PlaymateCategoryData>? = null
    private var filterPlaymate = false
    private var inviteMicIndex: Int? = null
    fun enableFilter(filter: Boolean) {
        this.enableFilter = filter
    }

    fun filterPlaymate(filter: Boolean) {
        this.filterPlaymate = filter
    }

    fun inviteMicIndex(index: Int) {
        this.inviteMicIndex = index
    }

    override val dimAmount: Float = 0.7f

    override fun initViews() {
        super.initViews()

        binding.btnFilter.show(enableFilter)
        binding.btnFilter.onClick {
            showFilter()
        }

        binding.vRefresh.setEnableRefresh(true)
        binding.vRefresh.setEnableLoadMore(true)
        binding.vRefresh.setEnableAutoLoadMore(true)
        binding.vRefresh.setOnRefreshLoadMoreListener(object : OnRefreshLoadMoreListener {
            override fun onRefresh(refreshLayout: RefreshLayout) {
                loadData()
            }

            override fun onLoadMore(refreshLayout: RefreshLayout) {
                inviteViewModel.loadMore()
            }
        })

        listAdapter.register(
            RoomMemberViewBinder(
                onAvatarClick = { item, position ->
                    onAvatarClick(item)
                },
                onInviteClick = { item, position ->
                    invite(item, position)
                }
            ))
        binding.rvList.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
        binding.rvList.adapter = listAdapter

        binding.vErrorView.setTitleColor(getCompatColor(APP_R.color.white))
        binding.vErrorView.setSubTitleColor(getCompatColor(APP_R.color.white))
    }

    override fun observeViewModel() {
        super.observeViewModel()
        inviteViewModel.totalLD.observe(viewLifecycleOwner) {
            val totalStr = it.toString()
            val text = getCompatString(R.string.room_member_count_in_room, totalStr)
            binding.tvTitle.text = SpannableStringBuilder(text).apply {
                findAndSetSpan(
                    ForegroundColorSpan(getCompatColor(APP_R.color.color_FF3FBFBD)),
                    totalStr
                )
            }
        }
        inviteViewModel.memberListRltLD.observe(viewLifecycleOwner) { rlt ->
            binding.vRefresh.finishRefresh()
            binding.vRefresh.finishLoadMore()
            binding.vRefresh.setEnableLoadMore(inviteViewModel.hasMoreData())
            showFailedToast(rlt)
        }
        inviteViewModel.memberListResultLD.observe(viewLifecycleOwner) {
            if (it.isNullOrEmpty()) {
                binding.rvList.gone()
                binding.vErrorView.show(
                    errorEmptyResId = APP_R.drawable.common_follow_list_empty_ic,
                    title = APP_R.string.commonui_list_empty
                )
            } else {
                listAdapter.submitList(it)
                binding.rvList.show()
                binding.vErrorView.gone()
            }
        }
    }

    override fun loadData() {
        super.loadData()
        inviteViewModel.pullMemberList(filterPlaymate, filterPlaymateCategory?.map { it.code })
    }

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

    private fun invite(item: RoomMemberItemData, position: Int) {
        inviteViewModel.invite(item.data.uid, inviteMicIndex).observe(viewLifecycleOwner) { rlt ->
            when (rlt) {
                is Rlt.Failed -> {
                    showFailedToast(rlt)
                }

                is Rlt.Success -> {
                    item.invited = true
                    listAdapter.notifyItemChanged(position)
                }
            }
        }
    }

    private fun showFilter() {
        RoomPlaymateFilterDialog().apply {
            setListener(object : RoomPlaymateFilterDialog.OnCategorySelectListener {
                override fun onSelect(skill: PlaymateCategoryData) {
                    notifyMemberListRefresh(skill)
                }

                override fun onSelectAll() {
                    notifyMemberListRefresh(null)
                }
            })
            setCurrentSelect(filterPlaymateCategory?.firstOrNull()?.code)
        }.show(childFragmentManager)
    }

    private fun notifyMemberListRefresh(category: PlaymateCategoryData?) {
        this.filterPlaymateCategory = category?.let {
            listOf(it)
        }
        binding.tvFilter.text = category?.name ?: getCompatString(R.string.room_playmate_category_filter)
        binding.vRefresh.autoRefresh()
    }

}