package com.adealink.weparty.module.widget.form.dialog

import androidx.recyclerview.widget.GridLayoutManager
import com.adealink.frame.aab.util.getCompatString
import com.adealink.frame.base.fastLazy
import com.adealink.frame.mvvm.view.viewBinding
import com.adealink.frame.util.onClick
import com.adealink.weparty.R
import com.adealink.weparty.commonui.ext.clearItemDecoration
import com.adealink.weparty.commonui.ext.dp
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.recycleview.diffutil.BaseListDiffUtil
import com.adealink.weparty.commonui.recycleview.diffutil.BaseListItemData
import com.adealink.weparty.commonui.recycleview.itemdecoration.GridSpacingItemDecoration
import com.adealink.weparty.commonui.toast.util.showToast
import com.adealink.weparty.commonui.widget.BottomDialogFragment
import com.adealink.weparty.databinding.WidgetDialogChooseBinding
import com.adealink.weparty.module.widget.form.data.StepFieldConstant

abstract class ChooseItem(
    var selected: Boolean = false
): BaseListItemData {
    abstract fun getDisplayName(): String
}

data class MultipleChooseItem(
    val option: StepFieldConstant
) : ChooseItem() {
    override fun getDisplayName(): String {
        return option.value
    }

}

fun MultipleChooseItem?.sameWith(other: MultipleChooseItem?): Boolean {
    if (this == null && other == null) {
        return true
    }
    return this?.option?.key == other?.option?.key
            && this?.option?.value == other?.option?.value
}

class MultipleChoiceDialog : BottomDialogFragment(R.layout.widget_dialog_choose) {

    private val binding by viewBinding(WidgetDialogChooseBinding::bind)

    private var title: String? = null
    private var desc: String? = null
    private var chooseItemList = listOf<MultipleChooseItem>()
    private var callback: IChooseCallback? = null
    private var maxLimit: Int = Int.MAX_VALUE

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

    fun setTitle(title: String?) {
        this.title = title
    }

    fun setDesc(desc: String?) {
        this.desc = desc
    }

    fun setItemList(
        chooseItemList: List<MultipleChooseItem>?,
        selectItemList: List<MultipleChooseItem>?
    ) {
        this.chooseItemList = chooseItemList?.map { item ->
            MultipleChooseItem(item.option).apply {
                selected = selectItemList?.find { it.option.key == item.option.key } != null
            }
        } ?: emptyList()
    }

    fun setCallback(callback: IChooseCallback) {
        this.callback = callback
    }

    fun setMaxLimit(max: Int?) {
        this.maxLimit = if (max == null || max < 0) {
            Int.MAX_VALUE
        } else {
            max
        }
    }

    override fun initViews() {
        super.initViews()
        if (title.isNullOrEmpty()) {
            binding.tvTitle.gone()
        } else {
            binding.tvTitle.show()
            binding.tvTitle.text = title
        }

        if (desc.isNullOrEmpty()) {
            binding.tvDesc.gone()
        } else {
            binding.tvDesc.show()
            binding.tvDesc.text = desc
        }

        listAdapter.register(ChoiceItemViewBinder { item, position ->
            onSelect(item, position)
        })
        when {
            chooseItemList.size == 1 -> {
                binding.rvItems.layoutManager = GridLayoutManager(context, 1)
                binding.rvItems.clearItemDecoration()
                binding.rvItems.addItemDecoration(
                    GridSpacingItemDecoration(
                        1,
                        spacingH = 16.dp(),
                        spacingV = 20.dp(),
                        false
                    )
                )
            }

            chooseItemList.size == 2 -> {
                binding.rvItems.layoutManager = GridLayoutManager(context, 2)
                binding.rvItems.clearItemDecoration()
                binding.rvItems.addItemDecoration(
                    GridSpacingItemDecoration(
                        2,
                        spacingH = 16.dp(),
                        spacingV = 20.dp(),
                        false
                    )
                )
            }

            chooseItemList.size >= 3 -> {
                binding.rvItems.layoutManager = GridLayoutManager(context, 3)
                binding.rvItems.clearItemDecoration()
                binding.rvItems.addItemDecoration(
                    GridSpacingItemDecoration(
                        3,
                        spacingH = 16.dp(),
                        spacingV = 20.dp(),
                        false
                    )
                )
            }
        }
        binding.rvItems.adapter = listAdapter
        listAdapter.submitList(chooseItemList)

        binding.btnConfirm.onClick {
            confirm()
        }
    }

    private fun onSelect(item: ChooseItem, position: Int) {
        val nextSelected = !item.selected
        if (nextSelected) {
            //检查最大选择数量
            val selectCount = chooseItemList.filter { it.selected }.size
            if (selectCount >= maxLimit) {
                showToast(
                    getCompatString(
                        R.string.common_widget_multichoice_max_limit,
                        maxLimit.toString()
                    )
                )
                return
            }
        }
        item.selected = !item.selected
        listAdapter.notifyItemChanged(position)
    }

    private fun confirm() {
        callback?.onChoose(
            chooseItemList.filter { it.selected }
        )
        dismiss()
    }

    interface IChooseCallback {
        fun onChoose(items: List<MultipleChooseItem>)
    }

}