package com.adealink.weparty.account.register.fragment

import android.content.Intent
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.updateLayoutParams
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.adealink.frame.aab.util.getCompatString
import com.adealink.frame.base.AppBase
import com.adealink.frame.base.Rlt
import com.adealink.frame.base.fastLazy
import com.adealink.frame.mvvm.view.viewBinding
import com.adealink.frame.router.Router
import com.adealink.frame.util.onClick
import com.adealink.weparty.AppModule
import com.adealink.weparty.account.R
import com.adealink.weparty.account.databinding.FragmentRegisterSelectCategoryBinding
import com.adealink.weparty.account.register.Page
import com.adealink.weparty.account.register.adapter.CategoryListItemViewBinder
import com.adealink.weparty.account.register.viewmodel.RegisterProfileViewModel
import com.adealink.weparty.account.viewModel.AccountViewModelFactory
import com.adealink.weparty.commonui.BaseFragment
import com.adealink.weparty.commonui.ext.dp
import com.adealink.weparty.commonui.recycleview.adapter.MultiTypeListAdapter
import com.adealink.weparty.commonui.recycleview.diffutil.BaseListDiffUtil
import com.adealink.weparty.commonui.recycleview.itemdecoration.GridSpacingMultiSpanSizeItemDecoration
import com.adealink.weparty.commonui.toast.util.showFailedToast
import com.adealink.weparty.commonui.toast.util.showToast
import com.adealink.weparty.module.playmate.PlaymateModule
import com.adealink.weparty.module.playmate.data.PlaymateCategoryData
import com.adealink.weparty.module.profile.ProfileModule
import com.adealink.weparty.module.profile.data.EditUserInfo
import com.adealink.weparty.module.profile.data.UserInterest
import com.adealink.weparty.ui.category.adapter.CategoryListTitleViewBinder
import com.adealink.weparty.ui.category.data.CategoryItemData
import com.adealink.weparty.ui.category.data.CategoryListItemData
import com.adealink.weparty.ui.category.data.CategoryListTitleData
import com.adealink.weparty.util.applyImmersive
import com.adealink.weparty.R as APP_R

class SelectCategoryFragment : BaseFragment(R.layout.fragment_register_select_category),
    CategoryListItemViewBinder.OnSelectListener {

    companion object {
        const val TAG = "SelectCategoryFragment"
        private const val SPAN_COUNT = 3
    }

    private val binding by viewBinding(FragmentRegisterSelectCategoryBinding::bind)

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

    private val categoryViewModel by fastLazy { PlaymateModule.getPlaymateViewModel(this) }

    private val editViewModel by activityViewModels<RegisterProfileViewModel> { AccountViewModelFactory() }

    private val profileViewModel by fastLazy { ProfileModule.getProfileViewModel(this) }

    private lateinit var listLayoutManger: GridLayoutManager

    private var categoryList = listOf<CategoryItemData>()
    override fun initViews() {
        super.initViews()
        activity.applyImmersive { top ->
            binding.topBar.updateLayoutParams<ConstraintLayout.LayoutParams> {
                topMargin = top
            }
        }
        binding.topBar.backCallback = {
            editViewModel.goPage(Page.CompleteUserInfo)
        }
        binding.btnNext.text = getCompatString(R.string.account_register_go_home, AppBase.appName)
        binding.btnNext.onClick {
            nextStep()
        }

        binding.rvCategory.adapter = listAdapter
        listAdapter.register(CategoryListTitleViewBinder())
        listAdapter.register(CategoryListItemViewBinder(this))
        listLayoutManger = GridLayoutManager(context, SPAN_COUNT, RecyclerView.VERTICAL, false)
        listLayoutManger.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
            override fun getSpanSize(position: Int): Int {
                val data = listAdapter.items.getOrNull(position)
                if (data is CategoryListTitleData) {
                    return SPAN_COUNT
                }
                return 1
            }
        }
        binding.rvCategory.layoutManager = listLayoutManger
        binding.rvCategory.addItemDecoration(
            GridSpacingMultiSpanSizeItemDecoration(SPAN_COUNT, 12.dp(), 8.dp(), false)
        )
    }

    override fun loadData() {
        super.loadData()
        categoryViewModel?.pullAllCategory()
    }

    override fun observeViewModel() {
        super.observeViewModel()
        categoryViewModel?.allCategoryLD?.observe(viewLifecycleOwner) {
            val onlineList = mutableListOf<PlaymateCategoryData>()
            val activityList = mutableListOf<PlaymateCategoryData>()
            for (entry in it) {
                if (entry.isActivity()) {
                    activityList.add(entry)
                } else {
                    onlineList.add(entry)
                }
            }
            val itemList = mutableListOf<CategoryItemData>()
            for (data in onlineList) {
                itemList.add(CategoryListTitleData(data))

                for (subData in data.subCategoryList) {
                    itemList.add(CategoryListItemData(data.code, subData))
                }
            }
            for (data in activityList) {
                itemList.add(CategoryListTitleData(data))

                for (subData in data.subCategoryList) {
                    itemList.add(CategoryListItemData(data.code, subData))
                }
            }
            submitCategoryList(itemList)
        }
    }

    private fun submitCategoryList(list: List<CategoryItemData>) {
        this.categoryList = list
        listAdapter.submitList(list)
    }

    private fun getSelectedInterest(): List<UserInterest> {
        val interestList = mutableListOf<UserInterest>()
        for (data in categoryList) {
            if (data is CategoryListItemData) {
                if (data.selected) {
                    interestList.add(UserInterest(data.data.code, data.data.name))
                }
            }
        }
        return interestList
    }

    private fun nextStep() {
        val interestList = getSelectedInterest()
        if (interestList.isEmpty()) {
            showToast(R.string.account_register_interests_is_null)
            return
        }
        editViewModel.setInterests(interestList)

        showLoading()
        profileViewModel?.updateProfile(editViewModel.getEditUserInfo())
            ?.observe(viewLifecycleOwner) { rlt ->
                dismissLoading()
                when (rlt) {
                    is Rlt.Failed -> {
                        showFailedToast(rlt)
                    }

                    is Rlt.Success -> {
                        goHome()
                    }
                }
            }
    }

    private fun goHome() {
        val act = activity ?: return
        Router.build(act, AppModule.Main.PATH)
            .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
            .putExtras(act.intent)
            .start()
    }

    override fun onSelect(item: CategoryListItemData, pos: Int) {
        val nextSelected = !item.selected
        if (nextSelected) {
            val selectInterest = getSelectedInterest()
            if (selectInterest.size >= EditUserInfo.MAX_INTEREST_COUNT) {
                showToast(
                    getCompatString(
                        APP_R.string.common_cannot_select_more_interest,
                        EditUserInfo.MAX_INTEREST_COUNT.toString()
                    )
                )
                return
            }
        }
        item.selected = nextSelected
        listAdapter.notifyItemChanged(pos)
    }

}