package com.grkj.iscs.view.widget

import android.content.Context
import android.text.Editable
import android.text.TextWatcher
import android.util.AttributeSet
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.LinearLayout
import android.widget.PopupWindow
import androidx.appcompat.content.res.AppCompatResources
import com.grkj.iscs.R
import com.grkj.iscs.databinding.LayoutSelectableInputBinding
import com.grkj.iscs.databinding.LayoutSelectableinputSpinnerBinding
import com.grkj.iscs.util.CommonUtils
import com.manu.mdatepicker.MDatePicker
import com.zhy.adapter.recyclerview.CommonAdapter
import com.zhy.adapter.recyclerview.base.ViewHolder
import java.text.SimpleDateFormat
import java.util.Date

class SelectableInput(private val ctx: Context, attrs: AttributeSet) : LinearLayout(ctx, attrs) {

    companion object {
        const val MODE_INPUT = 0
        const val MODE_SELECT = 1
        const val MODE_DATE = 2
    }

    private var mBinding: LayoutSelectableInputBinding
    private var mDropdownView: View? = null
    private var mPopWindow: PopupWindow? = null
    private val mOptionList = mutableListOf<String>()
    private var isSkipListener: Boolean = true
    private var mSelectListener: OnSpinnerSelectListener? = null
    private var mTextChangeListener: OnTextChangeListener? = null
    var mSelectIdx: Int? = null
    private var mMode: Int = MODE_INPUT

    init {
        val root = View.inflate(ctx, R.layout.layout_selectable_input, this)
        mBinding = LayoutSelectableInputBinding.bind(root)

        val attrSet = ctx.obtainStyledAttributes(attrs, R.styleable.SelectableInput)

        val isRequired = attrSet.getBoolean(R.styleable.SelectableInput_required, false)
        mBinding.tvPrefix.visibility = if (isRequired) View.VISIBLE else View.INVISIBLE

        val isEnabled = attrSet.getBoolean(R.styleable.SelectableInput_enabled, true)
        mBinding.et.isEnabled = isEnabled

        val mode = attrSet.getInt(R.styleable.SelectableInput_mode, MODE_INPUT)
        setMode(mode)

        mBinding.tvName.text = attrSet.getString(R.styleable.SelectableInput_name)
        mBinding.et.hint = attrSet.getString(R.styleable.SelectableInput_edittext_hint)

        val textSize = attrSet.getDimension(R.styleable.SelectableInput_text_size, -1f)
        if (textSize != -1f) {
            mBinding.tvPrefix.textSize = CommonUtils.px2dip(textSize)
            mBinding.tvName.textSize = CommonUtils.px2dip(textSize)
            mBinding.et.textSize = CommonUtils.px2dip(textSize)
        }

        val editWidth = attrSet.getDimensionPixelSize(R.styleable.SelectableInput_edit_width, -1)
        if (editWidth != -1) {
            mBinding.et.width = editWidth
        }

        val editHeight = attrSet.getDimensionPixelSize(R.styleable.SelectableInput_edit_height, -1)
        if (editHeight != -1) {
            mBinding.et.height = editHeight
            mBinding.et.gravity = Gravity.LEFT
        }

        attrSet.recycle()
    }

    fun setEnableStatus(isEnabled: Boolean) {
        mBinding.et.isEnabled = isEnabled
        when (mMode) {
            // 选择模式、日期模式
            MODE_SELECT, MODE_DATE -> {
                mBinding.et.background = if (mBinding.et.isEnabled) {
                    AppCompatResources.getDrawable(ctx, R.drawable.selectable_input_spinner_bg)
                } else {
                    AppCompatResources.getDrawable(ctx, R.drawable.selectable_input_spinner_disabled_bg)
                }
            }
            // 输入模式
            MODE_INPUT -> {
                mBinding.et.background = if (mBinding.et.isEnabled) {
                    AppCompatResources.getDrawable(ctx, R.drawable.selectable_input_text_bg)
                } else {
                    AppCompatResources.getDrawable(ctx, R.drawable.selectable_input_text_disabled_bg)
                }
            }
        }
    }

    private fun setMode(mode: Int) {
        when (mode) {
            // 选择模式
            MODE_SELECT -> {
                mMode = MODE_SELECT

                mBinding.et.background = if (mBinding.et.isEnabled) {
                    AppCompatResources.getDrawable(ctx, R.drawable.selectable_input_spinner_bg)
                } else {
                    AppCompatResources.getDrawable(ctx, R.drawable.selectable_input_spinner_disabled_bg)
                }

                mBinding.et.inputType = 0

                mBinding.et.setOnClickListener {
                    if (mOptionList.isNotEmpty()) {
                        showDropdown()
                    }
                }

                mBinding.et.setOnTouchListener { view, _ ->
                    view.requestFocus()
                    return@setOnTouchListener false
                }
            }
            // 输入模式
            MODE_INPUT -> {
                mMode = MODE_INPUT

                mBinding.et.background = if (mBinding.et.isEnabled) {
                    AppCompatResources.getDrawable(ctx, R.drawable.selectable_input_text_bg)
                } else {
                    AppCompatResources.getDrawable(ctx, R.drawable.selectable_input_text_disabled_bg)
                }

                val textWatcher = object : TextWatcher {
                    override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}

                    override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
                        if (mBinding.et.hasFocus()) {
                            mTextChangeListener?.onTextChange(p0.toString())
                        }
                    }

                    override fun afterTextChanged(p0: Editable?) {}
                }

                mBinding.et.setOnFocusChangeListener { view, b ->
                    if (b) {
                        mBinding.et.addTextChangedListener(textWatcher)
                    } else {
                        mBinding.et.removeTextChangedListener(textWatcher)
                        val imm = ctx.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                        imm.hideSoftInputFromWindow(view.windowToken, 0)
                    }
                }
            }
            // 日期模式
            else -> {
                mMode = MODE_DATE

                mBinding.et.background = if (mBinding.et.isEnabled) {
                    AppCompatResources.getDrawable(ctx, R.drawable.selectable_input_spinner_bg)
                } else {
                    AppCompatResources.getDrawable(ctx, R.drawable.selectable_input_spinner_disabled_bg)
                }

                mBinding.et.inputType = 0

                mBinding.et.setOnClickListener {
                    MDatePicker.create(ctx)
                        .setCanceledTouchOutside(true)
                        .setGravity(Gravity.CENTER)
                        .setSupportTime(true)
                        .setTwelveHour(false)
                        .setOnDateResultListener {
                            setText(SimpleDateFormat("yyyy-MM-dd").format(Date(it)))
                            mTextChangeListener?.onTextChange(getText())
                        }
                        .build().show()
                }
            }
        }
    }

    fun setText(v: String?) {
        isSkipListener = true
        mBinding.et.setText(v)
        v?.let {
            mBinding.et.setSelection(it.length)
        }
        isSkipListener = false
    }

    fun getText(): String {
        return mBinding.et.text.toString()
    }

    fun setOptionList(list: MutableList<String>) {
        mOptionList.clear()
        mOptionList.addAll(list)
    }

    private fun showDropdown() {
        mDropdownView?:let {
            mDropdownView = LayoutInflater.from(ctx).inflate(R.layout.layout_selectableinput_spinner, null)
        }

        mPopWindow ?: let {
            mPopWindow = PopupWindow(context)
            mPopWindow?.contentView = mDropdownView
            mPopWindow?.width = mBinding.et.width
            mPopWindow?.height = ViewGroup.LayoutParams.WRAP_CONTENT
            mPopWindow?.isOutsideTouchable = true
            mPopWindow?.isFocusable = true

            val popBinding = LayoutSelectableinputSpinnerBinding.bind(mDropdownView!!)
            popBinding.rvOptions.adapter = object : CommonAdapter<String>(ctx, R.layout.item_rv_selectableinput_spinner, mOptionList) {
                override fun convert(holder: ViewHolder?, option: String?, position: Int) {
                    holder?.setText(R.id.tv_option, option)
                    holder?.setOnClickListener(R.id.tv_option) {
                        mBinding.et.setText(option)
                        mSelectListener?.onSelect(option, position)
                        mPopWindow?.dismiss()
                        mSelectIdx = position
                    }
                }
            }
        }

        mPopWindow?.showAsDropDown(mBinding.et)
    }

    fun setOnSpinnerSelectListener(onSpinnerSelectListener: OnSpinnerSelectListener) {
        mSelectListener = onSpinnerSelectListener
    }

    fun setOnTextChangeListener(onTextChangeListener: OnTextChangeListener) {
        mTextChangeListener = onTextChangeListener
    }

    interface OnSpinnerSelectListener {
        fun onSelect(str: String?, index: Int)
    }

    interface OnTextChangeListener {
        fun onTextChange(str: String?)
    }
}