package com.yidian.shenghuoquan.newscontent.widget

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
import android.text.InputFilter
import android.text.InputType
import android.text.Spanned
import android.util.AttributeSet
import android.view.Gravity
import androidx.appcompat.widget.AppCompatEditText
import com.yidian.common.utils.YdUiUtils
import com.yidian.shenghuoquan.newscontent.R
import java.util.regex.Pattern

/**
 * author : lidawei
 * date : 2021/6/1
 * description :
 */
@Suppress("DEPRECATION")
class NumberWithBorderEditText @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null,
    defStyle: Int = 0
) : AppCompatEditText(context, attributeSet, defStyle) {

    private var onTextChange: ((String) -> Unit)? = null

    //输入的数字个数
    private val inputCount = 4

    //间距
    private val gap = YdUiUtils.dip2px(4, context)
    private var borderPaint: Paint
    private var textPaint: Paint
    private val textSizeReal = 16
    private var borderStroke =3f
    private val selectedBorderColor = context.resources.getColor(R.color.color_1852F1)
    private val normalBorderColor = context.resources.getColor(R.color.edit_text_border_gray)
    private val textColor = context.resources.getColor(R.color.gray_333)
    private val borderWidth = YdUiUtils.dip2px(24, context)
    private val borderList by lazy { ArrayList<RectF>() }
    private val numberList by lazy { ArrayList<Triple<String,Float,Float>>() }
    private var content:String?=null
    private var startX = 0f
    private var startY = 0f

    init {
        isLongClickable = false
        setTextIsSelectable(false)
        isCursorVisible = false
        background = null

        inputType = InputType.TYPE_CLASS_PHONE or InputType.TYPE_NUMBER_VARIATION_NORMAL
        gravity = Gravity.START or Gravity.CENTER_VERTICAL
        textSize = textSizeReal.toFloat()

        borderPaint = Paint()
        borderPaint.isAntiAlias = true
        borderPaint.strokeWidth = borderStroke
        borderPaint.style = Paint.Style.STROKE

        textPaint = Paint()
        textPaint.isAntiAlias = true
        textPaint.textSize = YdUiUtils.dip2px(textSizeReal,context).toFloat()
        textPaint.color = textColor
        textPaint.style = Paint.Style.FILL
        content = ""
        repeat(inputCount) {
            borderList.add(RectF())
        }
        filters = arrayOf(InputFilter.LengthFilter(inputCount),NumberFilter())
    }


    fun getContentText():String{
        return content?:""
    }

    fun setOnTextChangeListener(onTextChange:(String)->Unit){
        this.onTextChange = onTextChange
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        //  强制设置宽度为wrap_content
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)
        var heightSize = MeasureSpec.getSize(heightMeasureSpec)
        val widthReal:Int = (borderWidth * inputCount + (inputCount - 1) + gap +borderStroke * inputCount*2).toInt()

        if (heightMode == MeasureSpec.AT_MOST || heightSize < borderWidth) {
            heightSize = (borderWidth+borderStroke*2).toInt()
        }
        calculatePerBorderPosition(heightSize)
        setMeasuredDimension(widthReal, heightSize)
    }

    override fun onTextChanged(
        text: CharSequence?,
        start: Int,
        lengthBefore: Int,
        lengthAfter: Int
    ) {
        if (content == null || text==null) return
        if (text.length>inputCount){
            setText(content)
            setSelection(content?.length?:0)
            inputType = InputType.TYPE_CLASS_PHONE
            return
        }
        content = text.toString()
        numberList.clear()
        //计算每个文字的绘制的宽高
        calculatePerBorderPosition(height)
        calculatePerNumPosition(content?:"")
        onTextChange?.invoke(content?:"")
    }

    private fun calculatePerBorderPosition(height: Int) {
        //让输入框在居中位置
        startY = ((height - borderWidth) / 2).toFloat()
        startX = borderStroke/2
        //初始化输入框
        borderList.forEach {
            it.set(startX, startY, (startX + borderWidth), startY + borderWidth)
            startX += borderWidth + gap
        }
    }
    private fun calculatePerNumPosition(content: String) {
        var startX = 0f
        content.forEach{c ->
            val measureText = textPaint.measureText(c.toString())
            val textStartX = startX+(borderWidth-measureText)/2
            numberList.add(Triple(c.toString(),textStartX,baseline.toFloat()))
            startX += borderWidth +gap
        }
    }

    override fun onDraw(canvas: Canvas?) {
        borderList.forEachIndexed { index, rectF ->
            if (index<content?.length?:0){
                borderPaint.color = selectedBorderColor
            }else{
                borderPaint.color = normalBorderColor
            }
            canvas?.drawRect(rectF,borderPaint)
        }
        numberList.forEach {
            canvas?.drawText(it.first,it.second,it.third,textPaint)
        }
    }

    class NumberFilter : InputFilter {
        override fun filter(
            source: CharSequence?,
            start: Int,
            end: Int,
            dest: Spanned?,
            dstart: Int,
            dend: Int
        ): CharSequence {
            if (source.isNullOrEmpty()) return ""
            if (Pattern.matches("[0-9]*",source)) return source
            return ""
        }
    }
}
