package com.adealink.weparty.room.applymic

import android.graphics.Color
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.BaseFragment
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.applymic.adapter.HostApplyMemberViewBinder
import com.adealink.weparty.room.applymic.data.APPLY_MIC_LIST_TYPE_ALL
import com.adealink.weparty.room.applymic.data.ApplyMicItemData
import com.adealink.weparty.room.applymic.viewmodel.ApplyMicViewModel
import com.adealink.weparty.room.databinding.FragmentRoomApplyMicListBinding
import com.adealink.weparty.room.sdk.service.roomService
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 HostApplyListFragment : BaseFragment(R.layout.fragment_room_apply_mic_list) {

    private val binding by viewBinding(FragmentRoomApplyMicListBinding::bind)

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

    private val listViewModel by viewModels<ApplyMicViewModel>()

    private var searchType: Int = APPLY_MIC_LIST_TYPE_ALL

    private var showFilter: Boolean = false
    private var skillCategories: List<PlaymateCategoryData>? = null

    fun setSearchType(searchType: Int, showFilter: Boolean) {
        this.searchType = searchType
        this.showFilter = showFilter
    }

    override fun initViews() {
        super.initViews()

        binding.btnFilter.show(showFilter)
        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) {
                listViewModel.loadMoreList()
            }
        })

        listAdapter.register(
            HostApplyMemberViewBinder(
                onAvatarClick = { item, position ->
                    onAvatarClick(item)
                },
                onAcceptClick = { item, position ->
                    acceptApply(item, position)
                }
            ))
        binding.rvList.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
        binding.rvList.adapter = listAdapter

        binding.vErrorView.setTitleColor(Color.WHITE)
        binding.vErrorView.setSubTitleColor(Color.WHITE)

        binding.btnClear.onClick {
            clearAllApply()
        }
    }

    override fun observeViewModel() {
        super.observeViewModel()
        listViewModel.totalLD.observe(viewLifecycleOwner) {
            val totalStr = it.toString()
            val text = getCompatString(R.string.room_apply_mic_count_in_room, it.toString())
            binding.tvTitle.text = SpannableStringBuilder(text).apply {
                findAndSetSpan(
                    ForegroundColorSpan(getCompatColor(APP_R.color.color_FF3FBFBD)),
                    totalStr
                )
            }
        }

        listViewModel.applyListRltLD.observe(viewLifecycleOwner) { rlt ->
            binding.vRefresh.finishRefresh()
            binding.vRefresh.finishLoadMore()
            binding.vRefresh.setEnableLoadMore(listViewModel.hasMoreData())
            showFailedToast(rlt)
        }

        listViewModel.applyListLD.observe(viewLifecycleOwner) { list ->
            if (list.isNullOrEmpty()) {
                binding.rvList.gone()
                binding.vErrorView.show(
                    errorEmptyResId = APP_R.drawable.common_list_empty_ic,
                    title = APP_R.string.commonui_list_empty
                )
            } else {
                listAdapter.submitList(list)
                binding.rvList.show()
                binding.vErrorView.gone()
            }
        }
    }

    override fun loadData() {
        super.loadData()
        val roomId = roomService.joinController.getJoinedRoomId()
        if (roomId.isNullOrEmpty()) {
            return
        }
        listViewModel.pullList(roomId, searchType, skillCategories?.map { it.code })
    }

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

    private fun acceptApply(item: ApplyMicItemData, position: Int) {
        val roomId = roomService.joinController.getJoinedRoomId()
        if (roomId.isNullOrEmpty()) {
            return
        }
        showLoading()
        listViewModel.acceptApply(roomId, item.data.applyId, true).observe(viewLifecycleOwner) { rlt ->
            dismissLoading()
            when (rlt) {
                is Rlt.Failed -> {
                    showFailedToast(rlt)
                }

                is Rlt.Success<*> -> {
                    listViewModel.notifyApplyAccepted(item, position)
                }
            }

        }
    }

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

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

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

    private fun clearAllApply() {
        val roomId = roomService.joinController.getJoinedRoomId()
        if (roomId.isNullOrEmpty()) {
            return
        }
        showLoading()
        listViewModel.clearAllApply(roomId, searchType).observe(viewLifecycleOwner) { rlt ->
            dismissLoading()
            when (rlt) {
                is Rlt.Failed -> {
                    showFailedToast(rlt)
                }

                is Rlt.Success -> {
                    listViewModel.notifyClearAllApply()
                }
            }
        }
    }

}