package com.gh.common.view

import android.annotation.SuppressLint
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Typeface
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.CompoundButton
import android.widget.PopupWindow
import android.widget.RadioButton
import androidx.annotation.ColorInt
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.forEach
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.databinding.LayoutCategoryFilterBinding
import com.gh.gamecenter.databinding.LayoutCategoryFilterSizeBinding
import com.gh.gamecenter.databinding.PopCategoryFilterSizeBinding
import com.gh.gamecenter.databinding.PopCategoryFilterTypeBinding
import com.gh.gamecenter.entity.SubjectSettingEntity

class CategoryFilterView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {

    private val binding: LayoutCategoryFilterBinding

    private val mTypeFilterArray = arrayOf(SortType.RECOMMENDED, SortType.NEWEST, SortType.RATING)
    private val sizeFilterArray by lazy {
        listOf(
            SubjectSettingEntity.Size(min = -1, max = -1, text = "全部大小"),
            SubjectSettingEntity.Size(min = -1, max = 100, text = "100M以下"),
            SubjectSettingEntity.Size(min = 100, max = 300, text = "100-300M"),
            SubjectSettingEntity.Size(min = 300, max = 500, text = "300-500M"),
            SubjectSettingEntity.Size(min = 500, max = 1000, text = "500M-1G"),
            SubjectSettingEntity.Size(min = 1000, max = -1, text = "1G以上")
        )
    }

    private var mOnCategoryFilterSetupListener: OnCategoryFilterSetupListener? = null
    private var mOnFilterClickListener: OnFilterClickListener? = null

    private var mTypePopupWindow: PopupWindow? = null
    private var mSizePopupWindow: PopupWindow? = null

    init {

        val inflater = LayoutInflater.from(context)
        binding = LayoutCategoryFilterBinding.inflate(inflater, this, true)

        binding.ivTypeArrow.setImageResource(R.drawable.ic_arrow_down)
        binding.ivTypeArrow.imageTintList =
            ColorStateList.valueOf(com.gh.gamecenter.common.R.color.text_neutral.toColor(context))

        binding.ivSizeArrow.setImageResource(R.drawable.ic_arrow_down)
        binding.ivSizeArrow.imageTintList =
            ColorStateList.valueOf(com.gh.gamecenter.common.R.color.text_neutral.toColor(context))

        binding.tvType.text = mTypeFilterArray[0].value

        binding.llTypeContainer.setOnClickListener {
            mOnFilterClickListener?.onTypeClick()
            showSelectTypePopupWindow()
        }

        binding.llSizeContainer.setOnClickListener {
            mOnFilterClickListener?.onSizeClick()
            showSelectSizePopupWindow()
        }
    }

    fun setOnConfigSetupListener(onCategoryFilterSetupListener: OnCategoryFilterSetupListener) {
        mOnCategoryFilterSetupListener = onCategoryFilterSetupListener
    }

    fun setOnFilterClickListener(onFilterClickListener: OnFilterClickListener) {
        mOnFilterClickListener = onFilterClickListener
    }

    fun resetSortSize() {
        binding.tvType.text = R.string.size.toResString()
    }

    private fun showSelectTypePopupWindow() {
        binding.tvType.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(context))

        binding.ivTypeArrow.setImageResource(R.drawable.ic_arrow_up)
        binding.ivTypeArrow.imageTintList =
            ColorStateList.valueOf(com.gh.gamecenter.common.R.color.text_primary.toColor(context))

        val inflater = LayoutInflater.from(context)
        val typeBinding = PopCategoryFilterTypeBinding.inflate(inflater, null, false)
        val windowWidth = resources.displayMetrics.widthPixels - 80F.dip2px()
        val windowHeight = mOnCategoryFilterSetupListener?.getPopHeight() ?: 0
        val popupWindow = PopupWindow(
            typeBinding.root,
            windowWidth,
            if (windowHeight == 0) ViewGroup.LayoutParams.WRAP_CONTENT else (windowHeight - height)
        ).apply { mTypePopupWindow = this }


        typeBinding.root.setOnClickListener {
            popupWindow.dismiss()
        }

        val checkedId = when (binding.tvType.text.toString()) {
            "最新" -> R.id.rb_newest
            "评分" -> R.id.rb_score
            else -> R.id.rb_popular
        }

        val checkButton = typeBinding.root.findViewById<RadioButton>(checkedId)
        checkButton.setTypeface(checkButton.typeface, Typeface.BOLD)
        checkButton.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(context))
        checkButton.setDrawableEnd(R.drawable.ic_basic_checkmark_circle_fill)

        val onCheckedChangeListener = CompoundButton.OnCheckedChangeListener { button, isChecked ->
            if (isChecked) {
                button.setTypeface(button.typeface, Typeface.BOLD)
                button.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(context))
                button.setDrawableEnd(R.drawable.ic_basic_checkmark_circle_fill)

                val type = when (button.id) {
                    R.id.rb_newest -> SortType.NEWEST
                    R.id.rb_score -> SortType.RATING
                    else -> SortType.RECOMMENDED
                }
                binding.tvType.text = type.value
                mOnCategoryFilterSetupListener?.onSetupSortType(type)
                popupWindow.dismiss()
            } else {
                button.setTypeface(button.typeface, Typeface.NORMAL)
                button.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(context))
                button.setDrawableEnd(null)
            }
        }
        typeBinding.rgFilter.forEach {
            if (it is RadioButton) {
                it.setOnCheckedChangeListener(onCheckedChangeListener)
            }
        }

        popupWindow.setOnDismissListener {
            binding.tvType.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(context))
            binding.ivTypeArrow.setImageResource(R.drawable.ic_arrow_down)
            binding.ivTypeArrow.imageTintList =
                ColorStateList.valueOf(com.gh.gamecenter.common.R.color.text_neutral.toColor(context))
            mTypePopupWindow = null
        }

        popupWindow.isTouchable = true
        popupWindow.isFocusable = true
        popupWindow.animationStyle = 0
        popupWindow.showAsDropDown(this, 0, 0)
    }

    private fun showSelectSizePopupWindow() {
        binding.tvSize.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(context))
        binding.ivSizeArrow.setImageResource(R.drawable.ic_arrow_up)
        binding.ivSizeArrow.imageTintList =
            ColorStateList.valueOf(com.gh.gamecenter.common.R.color.text_primary.toColor(context))

        val inflater = LayoutInflater.from(context)
        val sizeBinding = PopCategoryFilterSizeBinding.inflate(inflater, null, false)
        val windowWidth = context.resources.displayMetrics.widthPixels - 80F.dip2px()
        val windowHeight = mOnCategoryFilterSetupListener?.getPopHeight() ?: 0
        val popupWindow = PopupWindow(
            sizeBinding.root,
            windowWidth,
            if (windowHeight == 0) ViewGroup.LayoutParams.WRAP_CONTENT else (windowHeight - height)
        ).apply { mSizePopupWindow = this }

        sizeBinding.root.setOnClickListener {
            popupWindow.dismiss()
        }
        sizeBinding.rvSize.setOnClickListener {
            // do  nothing
        }

        val sizeAdapter = CategoryFilterSizeAdapter {
            if (it.min == INVALID_SIZE && it.max == INVALID_SIZE) {
                binding.tvSize.text = R.string.size.toResString()
            } else {
                binding.tvSize.text = it.text
            }
            popupWindow.dismiss()
            mOnCategoryFilterSetupListener?.onSetupSortSize(it)
        }
        sizeBinding.rvSize.layoutManager = GridLayoutManager(context, 3, RecyclerView.VERTICAL, false)
        sizeBinding.rvSize.adapter = sizeAdapter
        val selectedPosition =
            sizeFilterArray.indexOfFirst { it.text?.contains(binding.tvSize.text.toString()) == true }

        sizeAdapter.setData(sizeFilterArray, selectedPosition)

        popupWindow.setOnDismissListener {
            binding.tvSize.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(context))
            binding.ivSizeArrow.setImageResource(R.drawable.ic_arrow_down)
            binding.ivSizeArrow.imageTintList =
                ColorStateList.valueOf(com.gh.gamecenter.common.R.color.text_neutral.toColor(context))
            mSizePopupWindow = null
        }

        popupWindow.isTouchable = true
        popupWindow.isFocusable = true
        popupWindow.animationStyle = 0
        popupWindow.showAsDropDown(this, 0, 0)
    }

    fun setRootBackgroundColor(@ColorInt color: Int) {
        findViewById<View>(R.id.config_controller).setBackgroundColor(color)
    }

    fun setItemTextColor(@ColorInt color: Int) {
        val colorInt = com.gh.gamecenter.common.R.color.text_neutral.toColor(context)
        binding.tvType.setTextColor(color)
        binding.tvSize.setTextColor(color)
        binding.ivTypeArrow.imageTintList = ColorStateList.valueOf(colorInt)
        binding.ivSizeArrow.imageTintList = ColorStateList.valueOf(colorInt)
    }

    fun updatePopupWindow() {
        when {
            mTypePopupWindow != null && mTypePopupWindow!!.isShowing -> {
                mTypePopupWindow?.dismiss()
                showSelectTypePopupWindow()
            }

            mSizePopupWindow != null && mSizePopupWindow!!.isShowing -> {
                mSizePopupWindow?.dismiss()
                showSelectSizePopupWindow()
            }
        }
    }

    interface OnCategoryFilterSetupListener {
        fun onSetupSortSize(sortSize: SubjectSettingEntity.Size)
        fun onSetupSortType(sortType: SortType)
        fun getPopHeight(): Int
    }

    interface OnFilterClickListener {
        fun onTypeClick()
        fun onSizeClick()
    }

    enum class SortType(val value: String) {
        RECOMMENDED("热门"),
        NEWEST("最新"),
        RATING("评分")
    }

    class CategoryFilterSizeAdapter(private val itemClick: (SubjectSettingEntity.Size) -> Unit) :
        RecyclerView.Adapter<CategoryFilterSizeAdapter.SizeViewHolder>() {

        private val dataList = arrayListOf<SubjectSettingEntity.Size>()
        private var selectedPosition = 0

        @SuppressLint("NotifyDataSetChanged")
        fun setData(data: List<SubjectSettingEntity.Size>, position: Int) {
            dataList.clear()
            dataList.addAll(data)
            selectedPosition = position
            notifyDataSetChanged()
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SizeViewHolder {
            return SizeViewHolder(parent.toBinding())
        }

        override fun getItemCount(): Int {
            return dataList.size
        }

        override fun onBindViewHolder(holder: SizeViewHolder, position: Int) {
            val item = dataList[position]
            val context = holder.binding.root.context
            if (selectedPosition == position) {
                holder.binding.root.setTextColor(com.gh.gamecenter.common.R.color.text_theme.toColor(context))
                holder.binding.root.setBackgroundResource(R.drawable.shape_category_filter_size_item_selected)
            } else {
                holder.binding.root.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(context))
                holder.binding.root.setBackgroundResource(R.drawable.shape_category_filter_size_item_normal)
            }
            holder.binding.root.text = item.text
            holder.binding.root.setOnClickListener {
                if (selectedPosition == holder.bindingAdapterPosition) {
                    return@setOnClickListener
                }
                val lastPosition = selectedPosition
                selectedPosition = holder.bindingAdapterPosition
                notifyItemChanged(lastPosition)
                notifyItemChanged(selectedPosition)
                itemClick(item)
            }
        }

        class SizeViewHolder(val binding: LayoutCategoryFilterSizeBinding) : RecyclerView.ViewHolder(binding.root)
    }

    companion object {
        private const val INVALID_SIZE = -1
    }
}