package cn.muchinfo.rma.view.autoWidget

import android.text.InputFilter
import android.text.InputType
import android.text.Spanned
import android.text.TextUtils
import android.text.method.NumberKeyListener
import android.view.inputmethod.EditorInfo
import android.widget.EditText
import java.math.BigDecimal
import java.util.regex.Pattern

/**
 * 设置带小数位的数量输入限制
 */
fun EditText.setDecimalInputType(maxValue: BigDecimal = BigDecimal("999999999.99"), decimals: Int = 2) {

    inputType = InputType.TYPE_CLASS_PHONE

    val inputFilters = arrayOfNulls<InputFilter>(1)
    val POINTER = "."
    val ZERO = "0"
    val pattern = Pattern.compile("([0-9]|\\.)*")
    inputFilters[0] = InputFilter { source, _, _, dest, dStart, dEnd ->
        val sourceText = source.toString()
        val destText = dest.toString()

        //验证删除等按键
        if (TextUtils.isEmpty(sourceText)) {
            return@InputFilter ""
        }

        // 头位输入.时添加0
        if (sourceText == "." && dStart == 0) {
            return@InputFilter "0."
        }

        // 输入后的文字
        val strAfterInput = StringBuilder(destText.substring(0, dStart))
                .append(sourceText)
                .append(destText.substring(dEnd, destText.length))
                .toString()

        val matcher = pattern.matcher(source)
        //已经输入小数点的情况下，只能输入数字
        if (destText.contains(POINTER)) {
            if (!matcher.matches()) {
                return@InputFilter ""
            } else {
                if (POINTER == source.toString()) {  //只能输入一个小数点
                    return@InputFilter ""
                }
            }

            //验证小数点精度，保证小数点后只能输入两位
            val index = destText.indexOf(POINTER)
            val length = dEnd - index

            if (length > decimals) {
                return@InputFilter dest.subSequence(dStart, dEnd)
            }
        } else {
            /**
             * 没有输入小数点的情况下，只能输入小数点和数字
             * 1. 首位不能输入小数点
             * 2. 如果首位输入0，则接下来只能输入小数点了
             */
            if (!matcher.matches()) {
                return@InputFilter ""
            } else {
                if (POINTER == source.toString() && TextUtils.isEmpty(destText)) {  //首位不能输入小数点
                    return@InputFilter ""
                } else if (POINTER != source.toString() && ZERO == destText) { //如果首位输入0，接下来只能输入小数点
                    return@InputFilter ""
                } else if (strAfterInput.indexOf(POINTER) > 0 && strAfterInput.length - strAfterInput.indexOf(POINTER) > 3) {// 点是打在最后两位以上的就不给打
                    return@InputFilter ""
                }
            }
        }

        //验证输入金额的大小
        val bigDecimal = BigDecimal(strAfterInput)
        if (bigDecimal.compareTo(maxValue) == 1) {// 大于设定的最大值
            return@InputFilter dest.subSequence(dStart, dEnd)
        }
        return@InputFilter StringBuilder(dest.subSequence(dStart, dEnd)).append(sourceText)
    }
    // input filter
    filters = inputFilters
}

fun EditText.setHexInputType() {
    setDigits("\\b(0[xX])?([A-Fa-f0-9]+)?\\b")
}

fun EditText.setIDCardType() {
    keyListener = object :NumberKeyListener() {
        override fun getInputType(): Int = EditorInfo.TYPE_CLASS_PHONE
        override fun getAcceptedChars(): CharArray = "1234567890xyzXYZ".toCharArray()
    }
}

private fun EditText.setDigits(regEx: String) {
    InputFilter { source, _, _, dest, dStart, dEnd ->
        val pattern = Pattern.compile(regEx)
        val strAfterInput = StringBuilder(dest.substring(0, dStart))
                .append(source)
                .append(dest.substring(dEnd, dest.length))
                .toString()
        val resultNotMatches = pattern.matcher(strAfterInput).matches().not()
        return@InputFilter if (resultNotMatches) {
            ""
        } else {
            source
        }
    }.let {
        // input filter
        filters = arrayOf(it)
    }
}

fun EditText.filterEmoji() {
    filters = arrayOf(object :InputFilter{
        var pattern = Pattern.compile("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]", Pattern.UNICODE_CASE or Pattern.CASE_INSENSITIVE)
        override fun filter(source: CharSequence?, start: Int, end: Int, dest: Spanned?, dstart: Int, dend: Int): CharSequence? {
            if (pattern.matcher(source).find()) {
                return ""
            }
            return null
        }
    })
}