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

import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
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.getActivity
import com.adealink.weparty.commonui.ext.gone
import com.adealink.weparty.commonui.ext.show
import com.adealink.weparty.databinding.WidgetSingleChooseBinding
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.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.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.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.StringStepField
import com.adealink.weparty.module.widget.form.data.StringStepFieldValue
import com.adealink.weparty.module.widget.form.dialog.SingleChoiceDialog
import com.adealink.weparty.module.widget.form.dialog.SingleChooseItem
import com.adealink.weparty.module.widget.form.dialog.sameWith
import com.adealink.weparty.R as APP_R


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

class SingleChoiceWidgetView(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = 0,
) : BaseWidgetView<SingleChoiceWidgetData>(context, attrs, defStyle) {

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

    private var initValue: SingleChooseItem? = null
    private var chooseItemList = listOf<SingleChooseItem>()
    private var selectItem: SingleChooseItem? = null

    init {
        binding.clContent.onClick {
            showChoice()
        }
    }


    override fun onViewCreated(lifecycleOwner: LifecycleOwner, widget: SingleChoiceWidgetData) {
        super.onViewCreated(lifecycleOwner, widget)
        chooseItemList = widget.fieldData.constants?.map { option ->
            SingleChooseItem(option)
        } ?: emptyList()
        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()
        }

        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
            }
        }
        if (!inputText.isNullOrEmpty()) {
            chooseItemList.find { it.option.key == inputText }?.let {
                this@SingleChoiceWidgetView.initValue = it
                this@SingleChoiceWidgetView.selectItem = it
                binding.tvContent.text = it.option.value
            }
        }
    }

    override fun validate(): Rlt<Any> {
        val widgetData = widgetData
        val validateData = widgetData?.fieldData?.validate
        if (widgetData == null || validateData == null) {
            return Rlt.Success(Unit)
        }

        if (validateData.required == true && selectItem == null) {
            return Rlt.Failed(
                RequireValueNullError(
                    getCompatString(
                        APP_R.string.common_widget_validate_require,
                        widgetData.fieldData.fieldName
                    )
                )
            )
        }

        return Rlt.Success(Unit)
    }


    override fun getFieldValue(): StepFieldValue? {
        val widgetData = widgetData ?: return null
        val inputValue = selectItem?.option?.key
        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
                )
            }
        }
    }

    private fun showChoice() {
        val widget = widgetData ?: return
        val act = context.getActivity() ?: return
        SingleChoiceDialog().apply {
            setTitle(widget.fieldData.fieldName)
            setDesc(widget.fieldData.fieldDesc)
            setItemList(chooseItemList)
            setCallback(object : SingleChoiceDialog.IChooseCallback {
                override fun onChoose(items: SingleChooseItem?) {
                    notifyItemsChanged(items)
                }
            })
        }.show(act.supportFragmentManager)
    }

    private fun notifyItemsChanged(item: SingleChooseItem?) {
        selectItem = item
        binding.tvContent.text = selectItem?.getDisplayName()
    }

    override fun hasEditFieldValue(): Boolean {
        val initValue = initValue
        val currentValue = selectItem
        return !initValue.sameWith(currentValue)
    }
}