package com.adealink.weparty.module.widget.form.field.multipletext

import android.annotation.SuppressLint
import android.content.Context
import android.text.Editable
import android.text.TextWatcher
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.inputmethod.EditorInfo
import androidx.lifecycle.LifecycleOwner
import com.adealink.frame.aab.util.getCompatString
import com.adealink.frame.base.Rlt
import com.adealink.frame.util.onClick
import com.adealink.weparty.commonui.commonSelectedDrawable
import com.adealink.weparty.commonui.ext.gone
import com.adealink.weparty.commonui.ext.isSuccess
import com.adealink.weparty.commonui.ext.show
import com.adealink.weparty.commonui.text.setMaxLength
import com.adealink.weparty.databinding.WidgetMultipleTextBinding
import com.adealink.weparty.util.formatNumberStr
import com.adealink.weparty.module.widget.form.BaseWidgetView
import com.adealink.weparty.module.widget.form.IWidgetData
import com.adealink.weparty.module.widget.form.WidgetType
import com.adealink.weparty.module.widget.form.data.ArrayLessThanMinError
import com.adealink.weparty.module.widget.form.data.ArrayMoreThanMaxError
import com.adealink.weparty.module.widget.form.data.DoubleArrayStepField
import com.adealink.weparty.module.widget.form.data.DoubleArrayStepFieldValue
import com.adealink.weparty.module.widget.form.data.DoubleStepField
import com.adealink.weparty.module.widget.form.data.DoubleStepFieldValue
import com.adealink.weparty.module.widget.form.data.FieldValidateError
import com.adealink.weparty.module.widget.form.data.IntegerArrayStepField
import com.adealink.weparty.module.widget.form.data.IntegerArrayStepFieldValue
import com.adealink.weparty.module.widget.form.data.IntegerStepField
import com.adealink.weparty.module.widget.form.data.IntegerStepFieldValue
import com.adealink.weparty.module.widget.form.data.NumberLessThanMinError
import com.adealink.weparty.module.widget.form.data.NumberMoreThanMaxError
import com.adealink.weparty.module.widget.form.data.RequireValueNullError
import com.adealink.weparty.module.widget.form.data.StepField
import com.adealink.weparty.module.widget.form.data.StepFieldValue
import com.adealink.weparty.module.widget.form.data.StringArrayStepField
import com.adealink.weparty.module.widget.form.data.StringArrayStepFieldValue
import com.adealink.weparty.module.widget.form.data.StringLessThanMinError
import com.adealink.weparty.module.widget.form.data.StringMoreThanMaxError
import com.adealink.weparty.module.widget.form.data.StringStepField
import com.adealink.weparty.module.widget.form.data.StringStepFieldValue
import com.adealink.weparty.R as APP_R


class MultipleTextWidgetData(
    override val fieldData: StepField<*>
) : IWidgetData {
    override fun widgetType(): WidgetType {
        return WidgetType.MULTIPLE_TEXT
    }

}

@SuppressLint("SetTextI18n")
class MultipleTextWidgetView(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = 0,
) : BaseWidgetView<MultipleTextWidgetData>(context, attrs, defStyle) {

    private val binding = WidgetMultipleTextBinding.inflate(LayoutInflater.from(context), this)

    private var initValue: String? = null

    init {
        binding.etInput.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(
                s: CharSequence?,
                start: Int,
                count: Int,
                after: Int
            ) {
            }

            override fun onTextChanged(
                s: CharSequence?,
                start: Int,
                before: Int,
                count: Int
            ) {
            }

            override fun afterTextChanged(s: Editable?) {
                val length = s?.length ?: 0

                binding.tvInputLength.text =
                    "${length}/${widgetData?.fieldData?.validate?.size?.max ?: 0}"
            }
        })
    }

    override fun onViewCreated(lifecycleOwner: LifecycleOwner, widget: MultipleTextWidgetData) {
        super.onViewCreated(lifecycleOwner, widget)
        if (widget.fieldData.fieldName.isEmpty()) {
            binding.tvTitle.gone()
        } else {
            binding.tvTitle.show()
            binding.tvTitle.text = widget.fieldData.fieldName
        }
        if (widget.fieldData.fieldDesc.isEmpty()) {
            binding.tvDesc.gone()
        } else {
            binding.tvDesc.show()
            binding.tvDesc.text = widget.fieldData.fieldDesc
        }
        if (widget.fieldData.example?.isValid() == true) {
            binding.btnExample.background = commonSelectedDrawable()
            binding.btnExample.show()
            binding.btnExample.onClick {
                showExampleDialog()
            }
        } else {
            binding.btnExample.gone()
        }

        if (widget.fieldData.validate?.size == null) {
            binding.tvInputLength.gone()
            binding.etInput.setMaxLength(Int.MAX_VALUE)
        } else {
            binding.tvInputLength.show()
            binding.tvInputLength.text = "${0}/${widget.fieldData.validate.size.max}"
            binding.etInput.setMaxLength(widget.fieldData.validate.size.max)
        }

        when (widget.fieldData) {
            is DoubleArrayStepField,
            is DoubleStepField -> {
                binding.etInput.inputType =
                    EditorInfo.TYPE_NUMBER_FLAG_DECIMAL or EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE or EditorInfo.TYPE_TEXT_FLAG_IME_MULTI_LINE
            }

            is IntegerArrayStepField,
            is IntegerStepField -> {
                binding.etInput.inputType =
                    EditorInfo.TYPE_CLASS_NUMBER or EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE or EditorInfo.TYPE_TEXT_FLAG_IME_MULTI_LINE
            }

            is StringArrayStepField,
            is StringStepField -> {
                binding.etInput.inputType =
                    EditorInfo.TYPE_CLASS_TEXT or EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE or EditorInfo.TYPE_TEXT_FLAG_IME_MULTI_LINE
            }
        }
        val inputText = when (widgetData?.fieldData) {
            is DoubleArrayStepField -> {
                (widgetData?.fieldData as DoubleArrayStepField).fieldValue?.joinToString(
                    separator = ","
                ) {
                    formatNumberStr(it, false)
                }
            }

            is DoubleStepField -> {
                (widgetData?.fieldData as DoubleStepField).fieldValue?.let {
                    formatNumberStr(it, false)
                }
            }

            is IntegerArrayStepField -> {
                (widgetData?.fieldData as IntegerArrayStepField).fieldValue?.joinToString(
                    separator = ","
                ) {
                    formatNumberStr(it, false)
                }
            }

            is IntegerStepField -> {
                (widgetData?.fieldData as IntegerStepField).fieldValue?.let {
                    formatNumberStr(it, false)
                }
            }

            is StringArrayStepField -> {
                (widgetData?.fieldData as StringArrayStepField).fieldValue?.joinToString(
                    separator = ","
                ) {
                    it
                }
            }

            is StringStepField -> {
                (widgetData?.fieldData as StringStepField).fieldValue
            }

            null -> {
                null
            }
        }
        initValue = inputText
        binding.etInput.setText(inputText)
    }

    override fun validate(): Rlt<Any> {
        val widgetData = widgetData
        if (widgetData == null) {
            return Rlt.Success(Unit)
        }
        val inputValue = binding.etInput.text?.toString()
        val rlt = when (widgetData.fieldData) {
            is DoubleArrayStepField -> {
                widgetData.fieldData.validate(
                    inputValue?.toDoubleOrNull()?.let {
                        listOf(it)
                    }
                )
            }

            is DoubleStepField -> {
                widgetData.fieldData.validate(
                    inputValue?.toDoubleOrNull()
                )
            }

            is IntegerArrayStepField -> {
                widgetData.fieldData.validate(
                    inputValue?.toIntOrNull()?.let {
                        listOf(it)
                    }
                )
            }

            is IntegerStepField -> {
                widgetData.fieldData.validate(
                    inputValue?.toIntOrNull()
                )
            }

            is StringArrayStepField -> {
                widgetData.fieldData.validate(
                    inputValue?.let {
                        listOf(it)
                    }
                )
            }

            is StringStepField -> {
                widgetData.fieldData.validate(
                    inputValue
                )
            }
        }
        return getValidateErrorMessage(rlt)
    }

    fun getValidateErrorMessage(rlt: Rlt<Any>): Rlt<Any> {
        if (rlt.isSuccess) {
            return rlt
        }
        val failRlt = rlt as Rlt.Failed
        if (failRlt.error is FieldValidateError) {
            val error = when (failRlt.error as FieldValidateError) {
                is RequireValueNullError -> {
                    RequireValueNullError(
                        getCompatString(
                            APP_R.string.common_widget_validate_require,
                            widgetData?.fieldData?.fieldName ?: ""
                        )
                    )
                }

                is NumberLessThanMinError -> {
                    NumberLessThanMinError(
                        getCompatString(
                            APP_R.string.common_widget_validate_number_min,
                            widgetData?.fieldData?.fieldName ?: "",
                            widgetData?.fieldData?.validate?.numLimit?.min ?: "",
                        )
                    )
                }

                is NumberMoreThanMaxError -> {
                    NumberLessThanMinError(
                        getCompatString(
                            APP_R.string.common_widget_validate_number_max,
                            widgetData?.fieldData?.fieldName ?: "",
                            widgetData?.fieldData?.validate?.numLimit?.max ?: "",
                        )
                    )
                }

                is StringLessThanMinError -> {
                    StringLessThanMinError(
                        getCompatString(
                            APP_R.string.common_widget_validate_size_min,
                            widgetData?.fieldData?.fieldName ?: "",
                            widgetData?.fieldData?.validate?.size?.min ?: "",
                        )
                    )
                }

                is StringMoreThanMaxError -> {
                    StringMoreThanMaxError(
                        getCompatString(
                            APP_R.string.common_widget_validate_size_max,
                            widgetData?.fieldData?.fieldName ?: "",
                            widgetData?.fieldData?.validate?.size?.max ?: "",
                        )
                    )
                }

                is ArrayLessThanMinError,
                is ArrayMoreThanMaxError -> {
                    //文本输入不支持这种类型校验
                    failRlt.error
                }
            }
            return Rlt.Failed(error)
        }
        return failRlt
    }

    override fun getFieldValue(): StepFieldValue? {
        val widgetData = widgetData ?: return null
        val inputValue = binding.etInput.text?.toString()
        return when (widgetData.fieldData) {
            is DoubleArrayStepField -> {
                DoubleArrayStepFieldValue(
                    widgetData.fieldData.fieldCode,
                    inputValue?.toDoubleOrNull()?.let {
                        listOf(it)
                    }
                )
            }

            is DoubleStepField -> {
                DoubleStepFieldValue(
                    widgetData.fieldData.fieldCode,
                    inputValue?.toDoubleOrNull()
                )
            }

            is IntegerArrayStepField -> {
                IntegerArrayStepFieldValue(
                    widgetData.fieldData.fieldCode,
                    inputValue?.toIntOrNull()?.let {
                        listOf(it)
                    }
                )
            }

            is IntegerStepField -> {
                IntegerStepFieldValue(
                    widgetData.fieldData.fieldCode,
                    inputValue?.toIntOrNull()
                )
            }

            is StringArrayStepField -> {
                StringArrayStepFieldValue(
                    widgetData.fieldData.fieldCode,
                    inputValue?.let {
                        listOf(it)
                    }
                )
            }

            is StringStepField -> {
                StringStepFieldValue(
                    widgetData.fieldData.fieldCode,
                    inputValue
                )
            }
        }
    }

    override fun hasEditFieldValue(): Boolean {
        val initValue = initValue
        val inputValue = binding.etInput.text?.toString()
        return initValue != inputValue
    }

}