package com.gh.gamecenter.common.view

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.text.*
import android.text.InputFilter.LengthFilter
import android.text.method.HideReturnsTransformationMethod
import android.text.method.PasswordTransformationMethod
import android.util.AttributeSet
import android.view.Gravity
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.TextView
import androidx.annotation.ColorInt
import androidx.core.content.ContextCompat
import com.gh.gamecenter.common.R


/**
 * Created by SongSenior on 2021/4/16
 * 一个 EditText 和 n 个 TextView
 */
class VerifyEditText @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) :
    LinearLayout(context, attrs, defStyleAttr) {
    private val mTextViewList: MutableList<TextView> = ArrayList()
    private var mEditText: EditText? = null
    private var drawableNormal: Drawable? = null
    private var drawableSelected: Drawable? = null
    private var textColor: Int
    private var mContext: Context? = null


    //输入过程监听
    private var mInputListener: InputListener? = null

    //输入完成监听
    private var mInputCompleteListener: InputCompleteListener? = null

    /**
     * view 添加到窗口时，延迟 500ms 弹出软键盘
     */
    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        mEditText?.postDelayed({ showSoftKeyBoard() }, 500)
    }

    /**
     * 设置背景
     * @param textView
     * @param drawable
     */
    private fun setTextViewBackground(textView: TextView, drawable: Drawable?) {
        if (drawable != null) textView.background = drawable
    }

    fun setTextViewStyle(normal: Drawable?, selected: Drawable?, @ColorInt color: Int) {
        drawableNormal = normal
        drawableSelected = selected
        textColor = color
        var isFirst = true
        for (i in mTextViewList.indices) {
            val textView = mTextViewList[i]
            if (textView.text.isNullOrEmpty() && isFirst) {
                isFirst = false
                setTextViewBackground(textView, drawableSelected)
            } else {
                setTextViewBackground(textView, drawableNormal)
            }
            textView.setTextColor(textColor)
        }
    }

    /**
     * 获取当前输入的内容
     *
     * @return
     */
    val content: String
        get() {
            val text = mEditText?.text
            return if (TextUtils.isEmpty(text)) "" else mEditText?.text.toString()
        }

    /**
     * 清除内容
     */
    fun clearContent() {
        mEditText?.setText("")
        for (i in mTextViewList.indices) {
            val textView = mTextViewList[i]
            textView.text = ""
            setTextViewBackground(textView, if (i == 0) drawableSelected else drawableNormal)
        }
    }

    /**
     * 设置默认的内容
     *
     * @param content
     */
    fun setDefaultContent(content: String) {
        mEditText?.setText(content)
        mEditText?.requestFocus()
        val chars = content.toCharArray()
        val min = chars.size.coerceAtMost(mTextViewList.size)
        for (i in 0 until min) {
            val aChar = chars[i]
            val s = aChar.toString()
            val textView = mTextViewList[i]
            textView.text = s
            setTextViewBackground(textView, drawableSelected)
        }
        if (mInputCompleteListener != null && min == mTextViewList.size) mInputCompleteListener?.onComplete(
            content.substring(0, min)
        )
    }

    /**
     * 显示软键盘
     */
    private fun showSoftKeyBoard() {
        val imm = mContext?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.showSoftInput(mEditText, InputMethodManager.SHOW_FORCED)
    }

    /**
     * 添加输入完成的监听
     *
     * @param inputCompleteListener
     */
    fun addInputCompleteListener(inputCompleteListener: InputCompleteListener?) {
        mInputCompleteListener = inputCompleteListener
        val content = mEditText?.text
        if (!TextUtils.isEmpty(content) && content.toString().length == mTextViewList.size) {
            mInputCompleteListener?.onComplete(content.toString())
        }
    }

    /**
     * 添加输入过程的监听
     *
     * @param inputListener
     */
    fun addInputListener(inputListener: InputListener?) {
        mInputListener = inputListener
        mInputListener?.onChange(mEditText?.text.toString())
    }

    interface InputCompleteListener {
        fun onComplete(content: String)
    }

    interface InputListener {
        fun onChange(content: String)
    }

    private fun px2sp(context: Context, pxValue: Float): Int {
        val fontScale = context.resources.displayMetrics.scaledDensity
        return (pxValue / fontScale + 0.5f).toInt()
    }

    private fun sp2px(context: Context, spValue: Float): Int {
        val fontScale = context.resources.displayMetrics.scaledDensity
        return (spValue * fontScale + 0.5f).toInt()
    }

    companion object {
        //默认 item 个数为 4 个
        private const val DEFAULT_ITEM_COUNT = 4

        //默认每个 item 的宽度为 100
        private const val DEFAULT_ITEM_WIDTH = 100

        //默认每个 item 的间距为 50
        private const val DEFAULT_ITEM_MARGIN = 50

        //默认每个 item 的字体大小为 14
        private const val DEFAULT_ITEM_TEXT_SIZE = 14

        //默认密码明文显示时间为 200ms，之后密文显示
        private const val DEFAULT_PASSWORD_VISIBLE_TIME = 200
    }

    init {
        mContext = context
        orientation = HORIZONTAL
        gravity = Gravity.CENTER
        @SuppressLint("CustomViewStyleable") val obtainStyledAttributes =
            getContext().obtainStyledAttributes(attrs, R.styleable.verify_EditText)
        drawableNormal =
            obtainStyledAttributes.getDrawable(R.styleable.verify_EditText_verify_background_normal)
        drawableSelected =
            obtainStyledAttributes.getDrawable(R.styleable.verify_EditText_verify_background_selected)
        textColor = obtainStyledAttributes.getColor(
            R.styleable.verify_EditText_verify_textColor,
            ContextCompat.getColor(context, R.color.black)
        )
        var count = obtainStyledAttributes.getInt(
            R.styleable.verify_EditText_verify_count,
            DEFAULT_ITEM_COUNT
        )
        val inputType = obtainStyledAttributes.getInt(
            R.styleable.verify_EditText_verify_inputType,
            InputType.TYPE_CLASS_NUMBER
        )
        val passwordVisibleTime = obtainStyledAttributes.getInt(
            R.styleable.verify_EditText_verify_password_visible_time,
            DEFAULT_PASSWORD_VISIBLE_TIME
        )
        val width = obtainStyledAttributes.getDimension(
            R.styleable.verify_EditText_verify_width,
            DEFAULT_ITEM_WIDTH.toFloat()
        )
            .toInt()
        val height =
            obtainStyledAttributes.getDimension(R.styleable.verify_EditText_verify_height, 0f)
                .toInt()
        val margin = obtainStyledAttributes.getDimension(
            R.styleable.verify_EditText_verify_margin,
            DEFAULT_ITEM_MARGIN.toFloat()
        )
            .toInt()
        val textSize = px2sp(
            context,
            obtainStyledAttributes.getDimension(
                R.styleable.verify_EditText_verify_textSize,
                sp2px(context, DEFAULT_ITEM_TEXT_SIZE.toFloat()).toFloat()
            )
        ).toFloat()
        val password =
            obtainStyledAttributes.getBoolean(R.styleable.verify_EditText_verify_password, false)
        obtainStyledAttributes.recycle()
        if (count < 2) count = 2 //最少 2 个 item
        mEditText = EditText(context)
        mEditText?.inputType = inputType
        mEditText?.layoutParams = LayoutParams(1, 1)
        mEditText?.isCursorVisible = false
        mEditText?.background = null
        mEditText?.filters = arrayOf<InputFilter>(LengthFilter(count)) //限制输入长度为 count
        mEditText?.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
            override fun onTextChanged(s: CharSequence, start: Int, before: Int, textCount: Int) {
                val textView = mTextViewList[start] //获取对应的 textview
                if (textCount == 1 && start < count - 1) {
                    setTextViewBackground(mTextViewList[start + 1], drawableSelected)
                }
                if (textCount == 0) {
                    if (start < count - 1) setTextViewBackground(
                        mTextViewList[start + 1],
                        drawableNormal
                    )
                    setTextViewBackground(textView, drawableSelected)
                } else {
                    setTextViewBackground(textView, drawableNormal)
                }
                if (before == 0) { //输入
                    val input = s.subSequence(start, s.length) //获取新输入的字
                    textView.text = input
                    if (password) { //如果需要密文显示
                        textView.transformationMethod =
                            HideReturnsTransformationMethod.getInstance()
                        //passwordVisibleTime 毫秒后设置为密文显示
                        textView.postDelayed(
                            {
                                textView.transformationMethod =
                                    PasswordTransformationMethod.getInstance()
                            },
                            passwordVisibleTime.toLong()
                        )
                    }
//                    setTextViewBackground(textView, drawableSelected)
                } else { //删除
                    textView.text = ""
//                    setTextViewBackground(textView, drawableNormal)
                }
                mInputListener?.onChange(s.toString())
                if (mInputCompleteListener != null && s.length == mTextViewList.size) mInputCompleteListener?.onComplete(
                    s.toString()
                )
            }

            override fun afterTextChanged(s: Editable) {}
        })
        addView(mEditText)
        //点击弹出软键盘
        setOnClickListener {
            mEditText?.requestFocus()
            showSoftKeyBoard()
        }
        //遍历生成 textview
        for (i in 0 until count) {
            val textView = TextView(context)
            textView.textSize = textSize
            textView.gravity = Gravity.CENTER
            textView.setTextColor(textColor)
            val layoutParams = LayoutParams(
                width,
                if (height == 0) ViewGroup.LayoutParams.WRAP_CONTENT else height
            )
            if (i == 0) layoutParams.leftMargin = -1 else layoutParams.leftMargin = margin
            textView.layoutParams = layoutParams
            setTextViewBackground(textView, if (i == 0) drawableSelected else drawableNormal)
            addView(textView)
            mTextViewList.add(textView)
        }
    }
}
