package com.develop.main.ui


import android.media.metrics.Event
import android.os.Bundle
import android.util.Log
import android.util.SparseIntArray
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout
import androidx.appcompat.widget.AppCompatTextView
import androidx.databinding.ViewDataBinding
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.develop.base.ext.globalApp
import com.develop.base.ext.navigateTo
import com.develop.base.ext.resId2Dimension
import com.develop.base.ext.updateText
import com.develop.base.widgets.CommonPopupWindow
import com.develop.common.data_repo.db.*
import com.develop.common.data_repo.db.entity.DevRecipeCategory
import com.develop.common.databinding.FragmentCommeListBinding
import com.develop.common.dialog.LoadingDialog
import com.develop.common.event.RefreshDataEvent
import com.develop.common.router.Screens
import com.develop.common.tag.*
import com.develop.common.ui.CommonBVMFragment
import com.develop.common.widget.*
import com.develop.main.R
import com.develop.main.databinding.FoodGridViewBinding
import com.develop.main.databinding.ItemFilterAndSortViewBinding
import com.develop.main.viewmodel.HomeViewModel
import com.drake.brv.BindingAdapter
import com.drake.brv.listener.OnMultiStateListener
import com.drake.brv.utils.*
import com.drake.net.time.Interval
import com.drake.net.utils.scopeNet
import com.scwang.smart.refresh.layout.api.RefreshLayout
import com.scwang.smart.refresh.layout.listener.OnMultiListener
import kotlinx.coroutines.delay
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe

class RecipesFragment : CommonBVMFragment<FragmentCommeListBinding, HomeViewModel>() {

    private var filterSortSearchView: HomeFilterSortSearchView? = null

    private var sortRv: RecyclerView? = null
    private var filterRv: RecyclerView? = null
    private var foodRecycle: RecyclerView? = null

    private var categoryDataList = mutableListOf<DevRecipeCategory>()
    private var sortDataList = mutableListOf<FilterSortModel>()
    private var currentHotWord = ""
    private var categoryCode: String = ""

    private val loadingDialog by lazy {
        LoadingDialog()
    }
    private var isRefresh = false

    private var needRefresh = false

    private val filterPopupWindow by lazy {
        CommonPopupWindow.ViewBuilder<FilterSortViewLayout>().width(dp417).height(dp549)
            .outsideTouchable(true).focusable(true).alpha(0.5f).clippingEnabled(false)
            .view(FilterSortViewLayout(hostActivity)).intercept { popupWindow, view ->

            }.onShowBefore { popupWindow, view ->
                filterRv = view.findViewById(com.develop.common.R.id.filter_recycle)
                filterRv?.apply {
                    linear()
                    setup {
                        addType<DevRecipeCategory>(R.layout.item_filter_and_sort_view)
                        onBind {
                            val model = getModel<DevRecipeCategory>()
                            bindFilterSortView(adapter, this, model.name ?: "", true)
                        }
                    }
                }?.models = categoryDataList
            }.build<ViewDataBinding>(hostActivity)
    }

    private val sortPopupWindow by lazy {
        CommonPopupWindow.ViewBuilder<FilterSortViewLayout>().width(dp417)
            .height(RelativeLayout.LayoutParams.WRAP_CONTENT).outsideTouchable(true).focusable(true)
            .alpha(0.5f).clippingEnabled(false).view(FilterSortViewLayout(hostActivity))
            .intercept { popupWindow, view ->

            }.onShowBefore { popupWindow, view ->
                sortRv = view.findViewById(com.develop.common.R.id.filter_recycle)
                sortRv?.apply {
                    linear()
                    setup {
                        addType<FilterSortModel>(R.layout.item_filter_and_sort_view)
                        onBind {
                            val model = getModel<FilterSortModel>()
                            bindFilterSortView(adapter, this, model.name, false)
                        }
                    }
                }?.models = sortDataList
            }.build<ViewDataBinding>(hostActivity)
    }


    override fun createViewModel(): HomeViewModel {
        return getViewModelOfActivity(HomeViewModel::class.java)
    }

    override fun createViewBinding(
        inflater: LayoutInflater, container: ViewGroup?
    ): FragmentCommeListBinding {
        EventBus.getDefault().register(this)
        return FragmentCommeListBinding.inflate(inflater, container, false)
    }

    override fun onPostCreateView() {
        super.onPostCreateView()
        initView()
        needRefresh = true
        initLiveDataCallback()

    }

    override fun onResume() {
        super.onResume()
        if (needRefresh) {
            refreshOnLineOrLocalRecipes()
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        EventBus.getDefault().unregister(this)
    }

    private fun initView() {
        sortDataList.addAll(DataFactory.genSortNameList(resources))

        binding.rv.apply {
            setHasFixedSize(true)
            isNestedScrollingEnabled = false
            linear()
            setup {
                addType<String>(HOME_TITLE_PROVIDER)
                addType<FilterSortModel>(HOME_FUNCTION_PROVIDER)
                addType<HomeBannerListModel>(HOME_BANNER_PROVIDER)
                addType<CommonSearchModel>(HOME_SEARCH_PROVIDER)
                addType<CategoryModel>(HOME_CATEGORY_PROVIDER)
                addType<FoodListModel>(HOME_FOOD_LIST_PROVIDER)
                onCreate {
                    if (it == HOME_FOOD_LIST_PROVIDER) {
                        foodRecycle = findView(R.id.food_recycle)
                        foodRecycle?.setHasFixedSize(true)
                        foodRecycle?.isNestedScrollingEnabled = false
                        foodRecycle?.setRecycledViewPool(recycledViewPool)
                        foodRecycle?.grid(4)
                        foodRecycle?.setup {
                            addType<FoodContentModel>(com.develop.common.R.layout.food_content_provider)
                            onBind {
                                findView<FoodContentView>(com.develop.common.R.id.food_content_view).setFoodContent(
                                    getModel()
                                )
                            }
                        }
                    }
                }
                onBind {
                    when (itemViewType) {
                        HOME_TITLE_PROVIDER -> {
                            if (!viewModel.isSearch) {
                                findView<AppCompatTextView>(R.id.tv_food_category_name).updateText(
                                    getModel()
                                )
                            }
                        }

                        HOME_FOOD_LIST_PROVIDER -> {
                            val foodListModel = getModel<FoodListModel>()
                            foodRecycle?.models = foodListModel.foodList
                        }

                        HOME_FUNCTION_PROVIDER -> {
                            filterSortSearchView =
                                findView<HomeFilterSortSearchView>(R.id.function_view)
                            filterSortSearchView?.apply {
                                if (!viewModel.isSearch) {
                                    resetView()
                                }
                                hideOnlineLayout(getModel<FilterSortModel>().isOnLineState)
                                onFunctionCallback = functionCallback
                            }
                        }

                        HOME_SEARCH_PROVIDER -> {
                            findView<CommonSearchLayout>(R.id.common_search_view).apply {
                                updateData(getModel())
                                onHotWordsSelectedListener = hotWordsSelectedCallback
                            }
                        }

                        HOME_CATEGORY_PROVIDER -> {
                            findView<CategoryTabViewLayout>(R.id.category_tab_view).apply {
                                val model = getModel<CategoryModel>()
                                updateCategorySize(
                                    model.allSize, model.recipesSize, model.ingredientSize
                                )
                                onCategoryTabSelectedListener = categoryTabSelectedCallback
                            }
                        }
                    }
                }
            }
            addOnScrollListener(object : RecyclerView.OnScrollListener() {
                override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                    super.onScrollStateChanged(recyclerView, newState)
                    when (newState) {

                        RecyclerView.SCROLL_STATE_IDLE -> {
                            Glide.with(hostActivity).resumeRequests()
                        }

                        RecyclerView.SCROLL_STATE_DRAGGING, RecyclerView.SCROLL_STATE_SETTLING -> {
                            Glide.with(hostActivity).pauseRequests()
                        }
                    }
                }
            })
        }
        binding.page.apply {
            setEnableRefresh(false)
            setEnableNestedScroll(false)
            setOnLoadMoreListener {
                isRefresh = false
                if (viewModel.isSearch) {
                    if (!viewModel.loadMoreForSearch()) {
                        finishLoadMoreWithNoMoreData()
                    }
                } else {
                    if (viewModel.recipesType == RecipesType.ONLINE) {
                        if (viewModel.currentPage < viewModel.totalPageSize) {
                            viewModel.getOnLineRecipeList(
                                categoryCode, viewModel.currCategoryName, isLoadMore = true
                            )
                        } else {
                            finishLoadMoreWithNoMoreData()
                        }
                    } else {
                        if (!viewModel.loadMoreLocalRecipes()) {
                            finishLoadMoreWithNoMoreData()
                        }
                    }
                }
            }
        }


    }


    /**排序/查询/过滤功能按钮回调 */
    private var functionCallback = object : HomeFilterSortSearchView.OnFunctionCallback {
        override fun onFilterClick(filterView: View) {
            filterRv?.models = categoryDataList
            filterPopupWindow.showAsDropDown(filterView, -dp5, 0)
        }

        override fun onSortClick(sortView: View) {
            sortRv?.models = sortDataList
            sortPopupWindow.showAsDropDown(sortView, -dp24, 0)
        }

        override fun onSearchClick() {
            viewModel.apply {
                isSearch = true
                homeOrBackLiveData.postValue(HomeOrBack.Back)
            }
            //进入搜索页
            if (viewModel.recipesType == RecipesType.ONLINE) {
                viewModel.getOnLineHotTags()
            } else {
                binding.rv.models = DataFactory.genTestSearchDataList()
            }
        }

        override fun onInputSearch(searchContent: String) {
            currentHotWord = searchContent
            loadingDialog.showDialog(childFragmentManager, "loadingDialog")
            if (viewModel.recipesType == RecipesType.ONLINE) {
                viewModel.getOnLineRecipeList("", currentHotWord)
            } else {
                viewModel.queryRecipesByHotWord(currentHotWord, CategoryType.All)
            }
        }

        override fun onDownloadClick() {
            navigateTo(Screens.Cook.FOOD_LIST) {
                val bundle = Bundle()
                bundle.putString(
                    FOOL_LIST_TITLE, globalApp().getString(com.develop.common.R.string.download)
                )
                bundle.putInt(FOOD_LIST_TYPE, Downloaded)
                with(bundle)
            }
        }

        override fun onOnlineRecipesClick() {
            viewModel.apply {
                loadingDialog.showDialog(childFragmentManager, "loadingDialog")
                getOnLineCategoryList()
                recipesType = RecipesType.ONLINE
                netFoodLiveData.postValue(true)
                homeOrBackLiveData.postValue(HomeOrBack.Back)
            }
        }

    }

    /**热词选择回调 */
    private var hotWordsSelectedCallback = object : CommonSearchLayout.OnHotWordsSelectedListener {
        override fun onHotWordsSelected(hotWord: String) {
            currentHotWord = hotWord
            loadingDialog.showDialog(childFragmentManager, "loadingDialog")
            if (viewModel.recipesType == RecipesType.ONLINE) {
                viewModel.getOnLineRecipeList("", currentHotWord)
            } else {
                viewModel.queryRecipesByHotWord(currentHotWord, CategoryType.All)
                filterSortSearchView?.updateHotWord(hotWord)
            }

        }

    }

    /**分类选择回调 */
    private var categoryTabSelectedCallback =
        object : CategoryTabViewLayout.OnCategoryTabSelectedListener {
            override fun onCurrentSelected(categoryType: CategoryType) {
                loadingDialog.showDialog(childFragmentManager, "loadingDialog")
                if (viewModel.recipesType == RecipesType.ONLINE) {
                    viewModel.getOnLineRecipeList("", currentHotWord)
                } else {
                    viewModel.queryRecipesByHotWord(currentHotWord, categoryType)
                }
            }

        }


    /**绑定过滤或排序内容*/
    private var filterSelectedPos = 0
    private var sortedSelectedPos = 0

    private fun bindFilterSortView(
        adapter: BindingAdapter,
        binder: BindingAdapter.BindingViewHolder,
        name: String,
        isFilter: Boolean
    ) {
        binder.apply {
            val binding = ItemFilterAndSortViewBinding.bind(itemView)
            val selectionPos = if (isFilter) {
                filterSelectedPos
            } else {
                sortedSelectedPos
            }
            binding.tvName.updateText(name)
            if (selectionPos == absoluteAdapterPosition) {
                binding.tvName.setTextColor(context.resources.getColor(checkedColor))
                binding.ivCheck.setBackgroundResource(icChecked)
            } else {
                binding.tvName.setTextColor(context.resources.getColor(unCheckedColor))
                binding.ivCheck.setBackgroundResource(0)
            }
            binding.itemLayout.setOnClickListener {
                if (isFilter) {
                    val tempPosition = filterSelectedPos
                    filterSelectedPos = absoluteAdapterPosition
                    adapter.notifyItemChanged(filterSelectedPos)
                    adapter.notifyItemChanged(tempPosition)
                    updateCategoryName(categoryDataList[absoluteAdapterPosition])
                    filterPopupWindow.dismiss()
                } else {
                    val tempPosition = sortedSelectedPos
                    sortedSelectedPos = absoluteAdapterPosition
                    adapter.notifyItemChanged(sortedSelectedPos)
                    adapter.notifyItemChanged(tempPosition)
                    updateSortName(absoluteAdapterPosition)
                    sortPopupWindow.dismiss()
                }
            }
        }
    }


    /**liveData回调*/
    private fun initLiveDataCallback() {
        viewModel.apply {

            refreshRecipesLiveData.observe(viewLifecycleOwner) {
                if (filterSortSearchView?.getOnlineLayoutVisible() != true) {
                    //从网络菜谱切回本地菜谱，更新数据
                    viewModel.recipesType = RecipesType.LOCAL
                }
                refreshOnLineOrLocalRecipes()
            }
            //获取本地菜谱分类回调
            localCategoryLiveData.observe(viewLifecycleOwner) {
                categoryDataList = it
                //默认All
                categoryDataList.add(
                    0, DevRecipeCategory(
                        "", "", getString(com.develop.common.R.string.all), null, null, null
                    )
                )
                updateCategoryName(categoryDataList[0])
                updateSortName(0, false)
                filterRv?.models = categoryDataList
            }

            //获取对应分类菜谱回调
            localRecipesLiveData.observe(viewLifecycleOwner) {
                needRefresh = false
                binding.page.finishRefresh()
                binding.rv.apply {
                    models = it
                    scrollToPosition(0)
                }
                scopeNet {
                    delay(300)
                    loadingDialog.removeSelf()
                }
            }

            //获取线上菜谱列表回调
            onLineRecipesLiveData.observe(viewLifecycleOwner) {
                binding.page.finishRefresh()
                binding.rv.apply {
                    models = it
                    scrollToPosition(0)
                }
                scopeNet {
                    delay(300)
                    loadingDialog.removeSelf()
                }
            }

            moreLocalRecipeLiveData.observe(viewLifecycleOwner) {
                foodRecycle?.addModels(it)
                binding.page.finishLoadMore(true)
            }

            moreSearchLocalRecipeLiveData.observe(viewLifecycleOwner) {
                foodRecycle?.addModels(it)
                binding.page.finishLoadMore(true)
            }

            //获取线上分类回调
            onlineCategoryLiveData.observe(viewLifecycleOwner) {
                categoryDataList = it
                categoryDataList.add(
                    0, DevRecipeCategory(
                        "", "", getString(com.develop.common.R.string.all), null, null, null
                    )
                )
                updateCategoryName(categoryDataList[0])
                updateSortName(0, false)
                filterRv?.models = categoryDataList
                binding.rv.scrollToPosition(0)
            }

            //获取线上热门标签回调
            onLineHotTagsLiveData.observe(viewLifecycleOwner) {
                binding.rv.models = DataFactory.genOnLineHotTags(it)
            }

            //搜索回调
            hotWordSearchRecipesLiveData.observe(viewLifecycleOwner) {
                binding.page.apply {
                    finishRefresh()
                }
                binding.rv.models = it
                binding.rv.scrollToPosition(0)
                loadingDialog.removeSelf()
            }
        }
    }


    /**更新分类名称并获取对应数据*/
    private fun updateCategoryName(devRecipeCategory: DevRecipeCategory) {
        loadingDialog.showDialog(childFragmentManager, "loadingDialog")
        viewModel.currCategoryName = devRecipeCategory.name ?: ""
        filterSortSearchView?.updateFilterName(
            viewModel.currCategoryName
        )
        if (viewModel.recipesType == RecipesType.ONLINE) {
            categoryCode = devRecipeCategory.code.toString()

            viewModel.getOnLineRecipeList(categoryCode, "")
        } else {
            categoryCode = devRecipeCategory.number.toString()
            isRefresh = true
            binding.page.resetNoMoreData()
            viewModel.queryLocalRecipes(categoryCode)
        }
    }

    /**更新分类排序并获取对应数据*/
    private fun updateSortName(pos: Int, needRefresh: Boolean = true) {
        loadingDialog.showDialog(childFragmentManager, "loadingDialog")
        filterSortSearchView?.updateSortName(
            sortDataList[pos].name
        )
        viewModel.sortedType = when (pos) {
            1 -> {
                SortedType.Popular
            }

            2 -> {
                SortedType.Newest
            }

            3 -> {
                SortedType.Score
            }

            0 -> {
                SortedType.A2Z
            }

            else -> {
                SortedType.A2Z
            }
        }
        if (needRefresh) {
            if (viewModel.recipesType == RecipesType.ONLINE) {
                viewModel.getOnLineRecipeList(categoryCode, "")
            } else {
                isRefresh = true
                binding.page.resetNoMoreData()
                viewModel.queryLocalRecipes(categoryCode)
            }
        }
    }

    private fun refreshOnLineOrLocalRecipes() {
        isRefresh = true
        if (viewModel.recipesType == RecipesType.ONLINE) {
            viewModel.apply {
                getOnLineCategoryList()
            }
        } else {
            viewModel.queryRecipesCategory()
        }
    }

    companion object {
        val HOME_TITLE_PROVIDER = R.layout.home_title_provider
        val HOME_FOOD_LIST_PROVIDER = R.layout.food_grid_view
        val HOME_BANNER_PROVIDER = R.layout.home_banner_provider
        val HOME_SEARCH_PROVIDER = R.layout.home_common_search_provider
        val HOME_CATEGORY_PROVIDER = R.layout.home_category_tab_provider
        val HOME_FUNCTION_PROVIDER = R.layout.home_function_provider

        var dp5 = (com.develop.base.R.dimen.convert_5px).resId2Dimension().toInt()
        var dp65 = (com.develop.base.R.dimen.convert_65px).resId2Dimension().toInt()
        var dp24 = (com.develop.base.R.dimen.convert_24px).resId2Dimension().toInt()
        var dp21 = (com.develop.base.R.dimen.convert_21px).resId2Dimension().toInt()
        var dp10 = (com.develop.base.R.dimen.convert_10px).resId2Dimension().toInt()
        var dp626 = (com.develop.base.R.dimen.convert_626px).resId2Dimension().toInt()
        var dp417 = (com.develop.base.R.dimen.convert_417px).resId2Dimension().toInt()
        var dp549 = (com.develop.base.R.dimen.convert_549px).resId2Dimension().toInt()
        var icChecked = com.develop.common.R.drawable.ic_check
        var checkedColor = com.develop.common.R.color.color_F4A12E
        var unCheckedColor = com.develop.common.R.color.color_6B6B6B
    }

    @Subscribe
    fun refreshRecipes(event: RefreshDataEvent) {
        refreshOnLineOrLocalRecipes()
    }
}