package com.lukouguoji.module_base.util

import androidx.databinding.ObservableBoolean
import com.lukouguoji.module_base.interfaces.ICheck
import dev.utils.common.ReflectUtils

object CheckUtil {

    /**
     * 校验是否全选
     */
    fun verifyAllChecked(list: List<ICheck>): Boolean {
        for (iCheck in list) {
            if (!iCheck.getCheckObservable().get()) {
                return false
            }
        }
        return true
    }

    /**
     * 校验是否全不选
     */
    fun verifyAllUnChecked(list: List<ICheck>): Boolean {
        for (iCheck in list) {
            if (iCheck.getCheckObservable().get()) {
                return false
            }
        }
        return true
    }

    /**
     * 全选
     */
    fun checkAll(list: List<ICheck>) {
        for (iCheck in list) {
            iCheck.getCheckObservable().set(true)
        }
    }

    /**
     * 全不选
     */
    fun unCheckAll(list: List<ICheck>) {
        for (iCheck in list) {
            iCheck.getCheckObservable().set(false)
        }
    }

    /**
     * 反选
     */
    fun reverseCheck(list: List<ICheck>) {
        for (iCheck in list) {
            iCheck.getCheckObservable().set(!iCheck.getCheckObservable().get())
        }
    }

    /**
     * 处理全选/全不选
     */
    fun handleAllCheck(list: List<ICheck>) {
        if (verifyAllChecked(list)) {
            unCheckAll(list)
        } else {
            checkAll(list)
        }
    }

    /**
     * 监听所有选中状态
     */
    fun listenAllCheck(list: List<ICheck>, listener: (Boolean) -> Unit) {
        for (iCheck in list) {
            iCheck.getCheckObservable().addOnPropertyChangedCallback(object :
                androidx.databinding.Observable.OnPropertyChangedCallback() {
                override fun onPropertyChanged(
                    sender: androidx.databinding.Observable?,
                    propertyId: Int
                ) {
                    listener.invoke(verifyAllChecked(list))
                }
            })
        }
    }

    /**
     * 处理单选
     * @param cancelAble 是否可取消
     */
    fun handleSingleCheck(
        list: List<Any>,
        fieldName: String,
        position: Int,
        cancelAble: Boolean = true
    ) {
        list.size < position && return
        val field = ReflectUtils.reflect(list[position]).field(fieldName).get<ObservableBoolean>()
        if (cancelAble && field.get()) {
            field.set(false)
            return
        }
        list.forEachIndexed { index, iCheck ->
            val itemField = ReflectUtils.reflect(iCheck).field(fieldName).get<ObservableBoolean>()
            if (itemField.get() != (index == position)) {
                itemField.set(index == position)
            }
        }
    }

}