package com.lukouguoji.module_base.ui.weight.search.layout

import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.widget.EditText
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.Spinner
import android.widget.TextView
import androidx.core.widget.doOnTextChanged
import androidx.databinding.InverseBindingListener
import com.lukouguoji.module_base.R
import com.lukouguoji.module_base.adapter.bindAdapter
import com.lukouguoji.module_base.adapter.bindOnSelected
import com.lukouguoji.module_base.adapter.loadImage
import com.lukouguoji.module_base.adapter.visible
import com.lukouguoji.module_base.interfaces.IOnFocusChangeListener
import com.lukouguoji.module_base.interfaces.IOnSpinnerSelected
import com.lukouguoji.module_base.ktx.formatDate
import com.lukouguoji.module_base.ktx.getActivity
import com.lukouguoji.module_base.ktx.loge
import com.lukouguoji.module_base.ktx.tryCatch
import com.lukouguoji.module_base.ui.weight.data.layout.AutoQueryConfig
import com.lukouguoji.module_base.ui.weight.search.layout.manager.SearchAutoQueryManager
import com.lukouguoji.module_base.util.Common
import dev.utils.app.info.KeyValue
import java.util.Calendar
import kotlin.properties.Delegates

class PadSearchLayout : LinearLayout {

    constructor(context: Context?) : super(context!!)
    constructor(context: Context?, attrs: AttributeSet?) : super(context!!, attrs)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context!!,
        attrs,
        defStyleAttr
    )


    var onChangeListener: InverseBindingListener? = null

    var ll: LinearLayout by Delegates.notNull()

    var tvM: TextView by Delegates.notNull()
    var tv: TextView by Delegates.notNull()

    var et: EditText by Delegates.notNull()
    var spinner: Spinner by Delegates.notNull()
    var iv: ImageView by Delegates.notNull()

    var type = SearchLayoutType.INPUT
        set(value) {
            field = value
            setForType()
            onValueSet()
        }

    var enable = true
        set(value) {
            field = value
            ll.isEnabled = value
            et.isEnabled = value
            spinner.isEnabled = value
        }

    var value = ""
        set(value) {
            if (field == value) {
                return
            }
            field = value
            onValueSet()
            onChangeListener?.onChange()
        }

    var hint = ""
        set(value) {
            field = value

            et.hint = value
            tv.hint = value
            // 下拉占位/选项字体与搜索输入框 hint(13sp) 保持一致
            bindAdapter(spinner, list, hint, R.layout.item_spinner_list_13sp)
        }

    var list = emptyList<KeyValue>()
        set(value) {
            field = value
            // 下拉占位/选项字体与搜索输入框 hint(13sp) 保持一致
            bindAdapter(spinner, value, hint, R.layout.item_spinner_list_13sp)
            onValueSet()
        }

    var required = false
        set(value) {
            field = value
            tvM.visibility = if (value) VISIBLE else GONE
        }

    var icon: Any? = null
        set(value) {
            field = value
            visible(iv, value)
            loadImage(iv, value)
        }

    /**
     * 自动查询配置
     */
    var autoQueryConfig: AutoQueryConfig = AutoQueryConfig()

    /**
     * 自动查询管理器（延迟初始化）
     */
    private var autoQueryManager: SearchAutoQueryManager? = null

    // 选择日期
    private val dateClick: (v: View) -> Unit = {
        if (enable) {
            Common.onYearMonthDay(context.getActivity(), value) { year, month, day ->
                val calendar = Calendar.getInstance()
                calendar.set(year, month - 1, day)
                value = calendar.time.formatDate()
                refreshCallBack?.invoke()
            }
        }
    }

    /**
     * 刷新事件回调
     */
    var refreshCallBack: (() -> Unit)? = {}

    var listRefreshCallBack: (() -> Unit)? = {}

    ///////////////////////////////////////////////////////////////////////////
    // 方法区
    ///////////////////////////////////////////////////////////////////////////

    init {
        val view = inflate(context, R.layout.layout_pad_search, this)

        ll = view.findViewById(R.id.ll)
        tvM = view.findViewById(R.id.tv_m)
        tv = view.findViewById(R.id.tv)
        et = view.findViewById(R.id.et)
        spinner = view.findViewById(R.id.spinner)
        iv = view.findViewById(R.id.iv)

        et.doOnTextChanged { text, _, _, _ ->
            value = text.toString()
        }
        bindOnSelected(spinner, object : IOnSpinnerSelected {
            override fun onSelected(position: Int) {
                value = list.getOrNull(position)?.value ?: ""
                refreshCallBack?.invoke()
            }
        })

        // 监听输入框焦点变化
        com.lukouguoji.module_base.adapter.setOnFocusChangeListener(
            et, object : IOnFocusChangeListener {
                override fun onFocusChange(hasFocus: Boolean) {
                    if (!hasFocus) {
                        refreshCallBack?.invoke()
                    }
                }
            })

        setForType()
    }

    /**
     * 启用自动查询功能
     */
    fun enableAutoQuery(config: AutoQueryConfig) {
        this.autoQueryConfig = config
        if (config.isValid()) {
            // 初始化查询管理器
            autoQueryManager = SearchAutoQueryManager(et, config) { newValue ->
                // 更新值的回调
                this.value = newValue
            }
            autoQueryManager?.attach()
        }
    }

    /**
     * 销毁时清理资源
     */
    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        autoQueryManager?.detach()
        autoQueryManager = null
    }

    private fun setForType() {
        when (type) {
            SearchLayoutType.INPUT -> {
                et.visibility = VISIBLE
                spinner.visibility = GONE
                tv.visibility = GONE
                setOnClickListener(null)
            }
            SearchLayoutType.INTEGER -> {
                et.visibility = VISIBLE
                spinner.visibility = GONE
                tv.visibility = GONE
                setOnClickListener(null)
            }

            SearchLayoutType.SPINNER -> {
                spinner.visibility = VISIBLE
                et.visibility = GONE
                tv.visibility = GONE
                setOnClickListener(null)
            }

            SearchLayoutType.DATE -> {
                tv.visibility = VISIBLE
                spinner.visibility = GONE
                et.visibility = GONE

                setOnClickListener(dateClick)
            }
        }
    }

    private fun onValueSet() {
        when (type) {
            SearchLayoutType.INPUT -> {
                if (et.text.toString() != value) {
                    et.setText(value)
                }
            }

            SearchLayoutType.INTEGER -> {
                var stringAnInt = isStringAnInt(et.text.toString())
                if (stringAnInt && et.text.toString() != value ) {
                    et.setText(value)
                }
            }

            SearchLayoutType.SPINNER -> {
                if (value.isNotEmpty()) {
                    val position = list.indexOfFirst { it.value == value }
                    if (position >= 0) {
                        spinner.setSelection(position)
                    }
                }
            }

            SearchLayoutType.DATE -> {
                tv.text = value
            }
        }
    }

    /**
     * 判断是否是数字
     */
    fun isStringAnInt(str: String?): Boolean {
        return str?.toIntOrNull() != null
    }


    /**
     * 重置数据
     */
    fun reset() {
        value = ""
        if (type == SearchLayoutType.SPINNER && list.isNotEmpty()) {
            spinner.setSelection(
                if (hint.isEmpty()) list.size - 1 else list.size
            )
        }
    }
}

enum class SearchLayoutType {
    INPUT, // 文本
    SPINNER, // 下拉选择
    DATE, // 日期
    INTEGER,//数字
}