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.Gravity
import android.view.View
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.databinding.InverseBindingListener
import com.lukouguoji.module_base.R
import dev.utils.app.info.KeyValue

/**
 * 手机版状态 Tab 条（5.5 寸手持端公共组件）
 *
 * 每个 Tab = 文字 + 可选角标数字，选中态为「深色加粗文字 + 底部 2dp 全宽指示条」。
 * 对应设计稿各列表页的「待交接 / 已交接」「全部 / 待移库 / 已移库」等状态切换栏。
 *
 * XML 用法：
 * ```xml
 * <com.lukouguoji.module_base.ui.weight.phone.PhoneStatusTab
 *     android:layout_width="match_parent"
 *     android:layout_height="wrap_content"
 *     tabs="@{viewModel.handoverStateTabs}"
 *     counts="@{viewModel.handoverStateCounts}"
 *     value="@={viewModel.handoverState}"
 *     setOnTabChanged="@{()-> activity.onTabChanged()}" />
 * ```
 *
 * [tabs] 用 [KeyValue]：`key` 为显示文字，`value` 为写回 [value] 的业务值。
 * [counts] 为与 tabs 等长的角标文案列表，传 null 或空串则该 Tab 不显示角标。
 */
class PhoneStatusTab @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {

    /**
     * 同一页面可能出现多个含内部 id 的手机版复合组件，系统按 id 保存/恢复视图状态会跨实例串档。
     * 这里只保存/恢复自身状态、不下发给子控件；选中值由 ViewModel + DataBinding 持有，无需视图级恢复。
     */
    override fun dispatchSaveInstanceState(container: SparseArray<Parcelable>) {
        dispatchFreezeSelfOnly(container)
    }

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

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

    /** Tab 切换回调（用户点击引起的变化才触发，外部赋值不触发） */
    var tabChangedCallBack: (() -> Unit)? = null

    var tabs: List<KeyValue> = emptyList()
        set(v) {
            field = v
            buildTabs()
        }

    var counts: List<String> = emptyList()
        set(v) {
            field = v
            refreshState()
        }

    var value: String = ""
        set(v) {
            if (field == v) return
            field = v
            refreshState()
            onChangeListener?.onChange()
        }

    init {
        orientation = HORIZONTAL
        setBackgroundColor(ContextCompat.getColor(context, R.color.white))
    }

    private fun buildTabs() {
        removeAllViews()
        tabs.forEachIndexed { index, tab ->
            addView(createTab(tab, index))
        }
        refreshState()
    }

    private fun createTab(tab: KeyValue, index: Int): View {
        val column = LinearLayout(context).apply {
            orientation = VERTICAL
            layoutParams = LayoutParams(0, LayoutParams.WRAP_CONTENT, 1f)
            setOnClickListener {
                val target = tab.value ?: ""
                if (value != target) {
                    value = target
                    tabChangedCallBack?.invoke()
                }
            }
        }

        // 文字 + 角标
        val row = LinearLayout(context).apply {
            orientation = HORIZONTAL
            gravity = Gravity.CENTER
            layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, dp(42))
        }
        row.addView(TextView(context).apply {
            id = titleIdOf(index)
            text = tab.key
            textSize = 14f
            setTypeface(typeface, android.graphics.Typeface.BOLD)
        })
        row.addView(TextView(context).apply {
            id = badgeIdOf(index)
            textSize = 11f
            gravity = Gravity.CENTER
            setBackgroundResource(R.drawable.bg_phone_badge)
            setTextColor(ContextCompat.getColor(context, R.color.phone_primary))
            setPadding(dp(6), dp(1), dp(6), dp(1))
            layoutParams = LayoutParams(
                LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT
            ).apply { marginStart = dp(6) }
        })
        column.addView(row)

        // 底部指示条
        column.addView(View(context).apply {
            id = indicatorIdOf(index)
            layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, dp(2))
        })

        return column
    }

    private fun refreshState() {
        tabs.forEachIndexed { index, tab ->
            val selected = (tab.value ?: "") == value

            findViewById<TextView>(titleIdOf(index))?.setTextColor(
                ContextCompat.getColor(
                    context,
                    if (selected) R.color.phone_text_title else R.color.phone_text_body
                )
            )

            findViewById<View>(indicatorIdOf(index))?.setBackgroundColor(
                if (selected) ContextCompat.getColor(context, R.color.phone_text_title)
                else android.graphics.Color.TRANSPARENT
            )

            findViewById<TextView>(badgeIdOf(index))?.apply {
                val count = counts.getOrNull(index).orEmpty()
                if (count.isEmpty()) {
                    visibility = GONE
                } else {
                    visibility = VISIBLE
                    text = count
                }
            }
        }
    }

    private fun dp(value: Int): Int =
        (value * resources.displayMetrics.density).toInt()

    // 动态生成的子 View 用固定偏移量作为 id，避免与资源 id 冲突
    private fun titleIdOf(index: Int) = ID_BASE_TITLE + index
    private fun badgeIdOf(index: Int) = ID_BASE_BADGE + index
    private fun indicatorIdOf(index: Int) = ID_BASE_INDICATOR + index

    companion object {
        private const val ID_BASE_TITLE = 0x7E100000
        private const val ID_BASE_BADGE = 0x7E200000
        private const val ID_BASE_INDICATOR = 0x7E300000
    }
}
