package com.lukouguoji.module_base.ui.weight.phone

import android.content.Context
import android.os.Parcelable
import android.util.AttributeSet
import android.util.SparseArray
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.EditText
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.core.widget.doOnTextChanged
import androidx.databinding.InverseBindingListener
import com.lukouguoji.module_base.R
import com.lukouguoji.module_base.ktx.setUpperCaseAlphanumericFilter

/**
 * 手机版搜索栏（5.5 寸手持端公共组件）
 *
 * 结构：圆角搜索框（放大镜 + 输入框 + 扫码图标）+ 右侧圆形筛选按钮。
 * 对应设计稿「5.5寸手持端设计文件」各列表页顶部搜索区。
 *
 * XML 用法：
 * ```xml
 * <com.lukouguoji.module_base.ui.weight.phone.PhoneSearchBar
 *     android:layout_width="match_parent"
 *     android:layout_height="wrap_content"
 *     hint="@{`搜索ULD编号`}"
 *     value="@={viewModel.uldNo}"
 *     upperCase="@{true}"
 *     setOnScanClickListener="@{(v)-> viewModel.scanUld()}"
 *     setOnFilterClickListener="@{(v)-> activity.toggleFilterPanel()}"
 *     setOnSearchListener="@{()-> viewModel.searchClick()}" />
 * ```
 *
 * 说明：与平板端 [com.lukouguoji.module_base.ui.weight.search.layout.PadSearchLayout] 并列，
 * 二者互不影响；手机布局用本组件，平板布局继续用 PadSearchLayout。
 */
class PhoneSearchBar @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {

    val llSearch: LinearLayout
    val ivSearch: ImageView
    val et: EditText
    val ivScan: ImageView
    val ivFilter: ImageView

    /** 双向绑定回调 */
    var onChangeListener: InverseBindingListener? = null

    /** 键盘「搜索」键 / 扫码完成后触发的查询回调 */
    var searchCallBack: (() -> Unit)? = null

    var value: String = ""
        set(v) {
            if (field == v) return
            field = v
            if (et.text.toString() != v) et.setText(v)
            onChangeListener?.onChange()
        }

    var hint: String = ""
        set(v) {
            field = v
            et.hint = v
        }

    /** 是否显示扫码图标（默认显示） */
    var showScan: Boolean = true
        set(v) {
            field = v
            ivScan.visibility = if (v) VISIBLE else GONE
        }

    /** 是否显示右侧筛选按钮（默认显示） */
    var showFilter: Boolean = true
        set(v) {
            field = v
            ivFilter.visibility = if (v) VISIBLE else GONE
        }

    /** 输入内容强制大写字母数字（运单号 / ULD 编号等场景） */
    var upperCase: Boolean = false
        set(v) {
            field = v
            if (v) et.setUpperCaseAlphanumericFilter()
        }

    init {
        orientation = HORIZONTAL
        gravity = android.view.Gravity.CENTER_VERTICAL
        inflate(context, R.layout.layout_phone_search_bar, this)

        llSearch = findViewById(R.id.ll_search)
        ivSearch = findViewById(R.id.iv_search)
        et = findViewById(R.id.et)
        ivScan = findViewById(R.id.iv_scan)
        ivFilter = findViewById(R.id.iv_filter)

        et.doOnTextChanged { text, _, _, _ ->
            value = text.toString()
        }

        // 软键盘「搜索」键触发查询
        et.setOnEditorActionListener { _, actionId, _ ->
            if (actionId == EditorInfo.IME_ACTION_SEARCH) {
                searchCallBack?.invoke()
                true
            } else {
                false
            }
        }
    }

    /**
     * 只保存/恢复自身状态，不下发给内部子控件。
     * 内部 et / iv_* 的 id 在每个实例中相同，交由系统按 id 恢复会跨实例串档；
     * 取值本就由 ViewModel + DataBinding 持有，无需视图级恢复。
     */
    override fun dispatchSaveInstanceState(container: SparseArray<Parcelable>) {
        dispatchFreezeSelfOnly(container)
    }

    override fun dispatchRestoreInstanceState(container: SparseArray<Parcelable>) {
        dispatchThawSelfOnly(container)
    }

    /** 供外部（如扫码回调）复用的图标点击入口 */
    fun setOnScanClick(listener: View.OnClickListener?) {
        ivScan.setOnClickListener(listener)
    }

    fun setOnFilterClick(listener: View.OnClickListener?) {
        ivFilter.setOnClickListener(listener)
    }
}
