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

import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.widget.EditText
import android.widget.FrameLayout
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 androidx.databinding.ObservableArrayList
import androidx.databinding.ObservableBoolean
import androidx.databinding.ObservableField
import androidx.databinding.ObservableInt
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.completeSpace
import com.lukouguoji.module_base.adapter.loadImage
import com.lukouguoji.module_base.adapter.setSelectedItem
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.util.Common
import dev.utils.app.info.KeyValue
import dev.utils.common.ReflectUtils
import java.util.Calendar
import kotlin.properties.Delegates

class PadDataLayout : FrameLayout {
    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 llContainer: LinearLayout by Delegates.notNull()
    var ll: LinearLayout by Delegates.notNull()
    var tvTitle: TextView by Delegates.notNull()
    var tvM: TextView by Delegates.notNull()
    var tv: TextView by Delegates.notNull()
    var tvSpinner: TextView by Delegates.notNull()

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

    var type = DataLayoutType.INPUT
        set(value) {
            field = value
            setForType()
        }
    var enable = true
        set(value) {
            field = value
            setForEnable()
        }
    var titleLength = 0
        set(value) {
            field = value
            if (value > 0) {
                completeSpace(tvTitle, value, false)
            }
        }

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

    var show = ""

    var title = ""
        set(value) {
            field = value
            tvTitle.text = value
        }

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

            et.hint = value
            bindAdapter(spinner, list, hint)
        }

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

    var list = emptyList<KeyValue>()
        set(value) {
            field = value
            bindAdapter(spinner, value, hint)
            onValueSet()
        }

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

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

    // 选择日期
    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()
            }
        }
    }

    init {
        initView()
    }

    private fun initView() {
        val view = inflate(context, R.layout.layout_pad_data, this)
        llContainer = view.findViewById(R.id.ll_container)
        ll = view.findViewById(R.id.ll)
        tvTitle = view.findViewById(R.id.tv_title)
        tvM = view.findViewById(R.id.tv_m)
        tv = view.findViewById(R.id.tv)
        tvSpinner = view.findViewById(R.id.tv_spinner)
        et = view.findViewById(R.id.et)
        spinner = view.findViewById(R.id.spinner)
        iv = view.findViewById(R.id.iv)

        // 默认单行，禁止换行（多行输入框通过 inputHeight 属性恢复为多行）
        et.isSingleLine = true
        et.maxLines = 1

        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()
    }

    private fun setForEnable() {
        ll.isEnabled = enable
        et.isEnabled = enable
        spinner.isEnabled = enable
        tv.isEnabled = enable

        setForType()
        onValueSet()
    }

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

            DataLayoutType.SPINNER -> {
                et.visibility = GONE
                tv.visibility = GONE
                if (enable) {
                    spinner.visibility = VISIBLE
                    tvSpinner.visibility = GONE
                } else {
                    tvSpinner.visibility = VISIBLE
                    spinner.visibility = GONE
                }
                setOnClickListener(null)
            }

            DataLayoutType.DATE -> {
                tv.visibility = VISIBLE
                et.visibility = GONE
                spinner.visibility = GONE
                tvSpinner.visibility = GONE
                iv.visibility = VISIBLE
                iv.setImageResource(R.mipmap.img_date)
                val dp20 = dev.utils.app.SizeUtils.dp2px(20f)
                iv.layoutParams.width = dp20
                iv.layoutParams.height = dp20

                setOnClickListener(dateClick)
            }
        }
    }

    private fun onValueSet() {
        if (et.text.toString() != value) {
            et.setText(value)
        }
        if (tv.text.toString() != value) {
            tv.text = value
        }

        tvSpinner.text = list.find { b -> b.value == value }?.key ?: value

        if (value.isNotEmpty() && list.isNotEmpty()) {
            val index = list.indexOfFirst { b -> b.value == value }
            if (index >= 0) {
                spinner.post {
                    spinner.setSelection(index)
                }
            }
        }
    }

    internal fun setOnValueChangeListener(listener: InverseBindingListener) {
        if (onChangeListener == null) {
            this.onChangeListener = listener
        }
    }
}

enum class DataLayoutType {
    INPUT, // 文本
    SPINNER, // 下拉选择
    DATE, // 日期
}
