package com.develop.step

import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.animation.LinearInterpolator
import android.widget.TextView
import androidx.activity.viewModels
import androidx.recyclerview.widget.RecyclerView
import com.alibaba.android.arouter.facade.annotation.Autowired
import com.alibaba.android.arouter.launcher.ARouter
import com.develop.food.base.data.ModesType
import com.develop.food.base.data.model.CookSettingType
import com.develop.food.base.repo.entity.DevRecipePortionSize
import com.develop.food.base.ui.BaseActivity
import com.develop.food.base.utils.ThreadUtils
import com.develop.food.base.utils.updateText
import com.develop.food.base.widgets.BCustomerLinearLayout
import com.develop.food.base.widgets.CancelConfirmDialog
import com.develop.food.base.widgets.CookProgressDrawable
import com.develop.step.databinding.ActivityFoodStep2Binding
import com.develop.step.details.CookDetailSourceAdapter
import com.develop.step.details.CookSourceItem
import com.develop.step.model.CookDetailInfo
import com.develop.step.viewmodel.CookStepViewModel
import com.develop.step.widgets.NoteEditDialog
import com.develop.step.widgets.RingControlView
import com.google.gson.Gson
import com.kuyuntech.cofarcooking.device.sdk.eventbus.core.DevInfo
import com.kuyuntech.cofarcooking.device.sdk.eventbus.event.DevStatusEvent
import com.kuyuntech.cofarcooking.device.sdk.util.core.CofarSDK
import org.greenrobot.eventbus.Subscribe
import java.math.BigDecimal
import java.util.*

abstract class CookStepToolActivity : BaseActivity<ActivityFoodStep2Binding>() {

    @JvmField
    @Autowired(name = "number")
    var recipeNumber: String? = null

    @JvmField
    @Autowired(name = "stepIndex")
    var currentStepIndex: Int = 0

    var runningState = 0

    val viewModel by viewModels<CookStepViewModel>()
    val cookProgressDrawable = CookProgressDrawable()
    private var turboTimer: Timer? = null

    val backRequestDialog by lazy {
        CancelConfirmDialog()
    }

    val overrideModeDialog by lazy {
        CancelConfirmDialog()
    }
    protected var whereIndex = -1

    private var isCookDetailDialogShow = false
    private var isCookStepDialogShow = false
    private var rotateAnimator: ObjectAnimator? = null
    private var rotateAnimDir = -1

    @JvmField
    @Autowired(name = "cook_step_detail")
    var cookStepDetail: String? = null


    @JvmField
    @Autowired(name = "portionSizelJson")
    var portionSizelJson: String? = null

    abstract fun clickNextStep()

    abstract fun clickPrevStep()

    abstract fun clickFirstButton(tag: String)

    abstract fun clickSecondButton(tag: String)

    abstract fun clickWeightTare()

    abstract fun onUserChangeTemp(value: Int)

    abstract fun onUserChangeSpeed(value: Int)

    abstract fun onDevStateChange(devInfo: DevInfo)

    /**
     * left => value = 0
     * right => value = 1
     */
    abstract fun onSettingDirection(value: Int)

    @SuppressLint("ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        hasShowScreenSaver = true
        ARouter.getInstance().inject(this)
//        EventBus.getDefault().register(this)
        binding.viewProgress.background = cookProgressDrawable
        binding.tvTitleStep.setOnClickListener {
            //showCookDetailDialog()
        }
        binding.tvStepName.setOnClickListener {
            showCookStepDetailDialog()
        }
        binding.viewRemark.setOnClickListener {
            NoteEditDialog().showDialog(supportFragmentManager, "NoteEditDialog")
        }
        binding.ivNextStep.setOnClickListener {
            clickNextStep()
            viewModel.stepUiData.doingModify = false
        }
        binding.ivPrevStep.setOnClickListener {
            clickPrevStep()
            viewModel.stepUiData.doingModify = false
        }
        binding.controller.clCookTemp.setOnClickListener {
            whereIndex = -1
            binding.controller.clSetTime.stopAlphaAnim()
            changeTempSettingPanel()
        }
        binding.controller.clCookTime.setOnClickListener {
            changeTimeSettingPanel()
        }
        binding.controller.clCookSpeed.setOnClickListener {
            whereIndex = -1
            binding.controller.clSetTime.stopAlphaAnim()
            changeSpeedSettingStep()
        }
        binding.controller.clCookDirection.setOnClickListener {
            whereIndex = -1
            binding.controller.clSetTime.stopAlphaAnim()
            changeDirectionSettingStep()
        }
        binding.viewBack.setOnClickListener {
            val run = recipeNumber?.let { it1 -> CofarSDK.devInfo().runningInstId.startsWith(it1) }
            if (runningState != 0 && run == true) {
                backRequestDialog.showDialog(supportFragmentManager, "backRequestDialog")
            } else {
                finish()
            }
        }

        binding.viewSource.setOnClickListener {
            showCookSourceDialog()
        }

        binding.viewStepMark.setOnClickListener {
            showCookStepDetailDialog()
        }

        binding.controller.btnStart.setOnClickListener {
            clickFirstButton((it.tag as? String) ?: BUTTON_TAG_START)
            viewModel.stepUiData.doingModify = false
        }
        binding.controller.btnReset.setOnClickListener {
            viewModel.stepUiData.doingModify = false
            clickSecondButton((it.tag as? String) ?: BUTTON_TAG_RESET)
        }
        binding.tvWeightTare.setOnClickListener {
            viewModel.stepUiData.doingModify = false
            clickWeightTare()
        }
        binding.controller.apply {
            tempRingView.setRange(0f, 100f)
            tempRingView.updateProgress(80)
            tempRingView.onRingViewListener = object : RingControlView.OnRingViewListener {
                override fun onProgressChange(progress: Int) {
                    viewModel.stepUiData.doingModify = true
                    onUserChangeTemp(progress)
                }
            }
            speedRingView.setRange(0f, 10f)
            speedRingView.updateProgress(2)
            speedRingView.onRingViewListener = object : RingControlView.OnRingViewListener {
                override fun onProgressChange(progress: Int) {
                    viewModel.stepUiData.doingModify = true
                    onUserChangeSpeed(progress)
                }
            }
        }
        binding.ivTurboView.setOnTouchListener { view, motionEvent ->
            when (motionEvent.action) {
                MotionEvent.ACTION_DOWN -> {
                    turboDownEvent()
                }

                MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> {
                    turboUpEvent()
                }
            }
            true
        }
        configureDirection()
        binding.scrollLayout.setOnGestureChangeListener(object :
            BCustomerLinearLayout.OnGestureChangeListener {
            override fun scrollLeft() {
                //向左手势
                clickNextStep()
            }

            override fun scrollRight() {
                //向右手势
                clickPrevStep()
            }

        })
    }

    private fun startTurbo() {
        turboTimer?.cancel()
        turboTimer = Timer()
        turboTimer?.schedule(object : TimerTask() {
            override fun run() {
                CofarSDK.start("")
                Log.d("ddddddd", "-----")
            }
        }, 0, 300)
    }

    private fun configureDirection() {
        binding.controller.tvTurnRight.setOnClickListener {
            viewModel.stepUiData.doingModify = true
            updateDirection(1)
            onSettingDirection(1)
        }
        binding.controller.tvTurnLeft.setOnClickListener {
            viewModel.stepUiData.doingModify = true
            updateDirection(0)
            onSettingDirection(0)
        }
    }


    fun updateDirection(directionValue: Int) {
        if (directionValue == 0) {
            binding.controller.ivDirection.rotationY = 180f
            binding.controller.tvTurnRight.setTextColor(0xffE5E5E5.toInt())
            binding.controller.tvTurnLeft.setTextColor(0xffE60012.toInt())
            binding.controller.tvSetDirection.updateText(getString(R.string.turn_right))
        } else {
            binding.controller.ivDirection.rotationY = 0f
            binding.controller.tvTurnRight.setTextColor(0xffE60012.toInt())
            binding.controller.tvTurnLeft.setTextColor(0xffE5E5E5.toInt())
            binding.controller.tvSetDirection.updateText(getString(R.string.turn_left))
        }
    }

    fun changeWeightPanel() {
        binding.controller.root.visibility = View.GONE
        binding.llWeightView.visibility = View.VISIBLE
        binding.ivTurboView.visibility = View.GONE
    }

    fun changeDescription() {
        binding.controller.root.visibility = View.GONE
        binding.llWeightView.visibility = View.GONE
        binding.ivTurboView.visibility = View.GONE
    }

    fun changeTurboPanel() {
        changeTempSettingPanel()
        binding.ivTurboView.visibility = View.VISIBLE
    }

    fun changeTempSettingPanel() {
        binding.llWeightView.visibility = View.GONE
        binding.controller.root.visibility = View.VISIBLE
        binding.controller.tempRingView.visibility = View.VISIBLE
        binding.controller.tvRingTempText.visibility = View.VISIBLE
        binding.controller.speedRingView.visibility = View.GONE
        binding.controller.tvSpeedText.visibility = View.GONE
        binding.controller.clSetTime.visibility = View.GONE
        binding.controller.flDirection.visibility = View.GONE
        if (viewModel.displayStep()?.isTurboMode() != true) {
            binding.ivTurboView.visibility = View.GONE
        }

        //蒸汽模式特殊处理
        if (viewModel.displayStep()?.workMode == ModesType.STEAM.name) {
            binding.controller.steamFire.visibility = View.VISIBLE;
            binding.controller.tvRingTempText.visibility = View.GONE;
            binding.controller.steamFireSmall.visibility = View.VISIBLE;
            binding.controller.tvCookingTempTarget.visibility = View.GONE;
        } else {
            binding.controller.steamFire.visibility = View.GONE;
            binding.controller.tvRingTempText.visibility = View.VISIBLE;
            binding.controller.steamFireSmall.visibility = View.GONE;
            binding.controller.tvCookingTempTarget.visibility = View.VISIBLE;

        }

        setPanelViewProperty(CookSettingType.TEMP_SETTING)
    }

    fun changeTimeSettingPanel() {
        binding.llWeightView.visibility = View.GONE
        binding.controller.root.visibility = View.VISIBLE
        binding.controller.tempRingView.visibility = View.INVISIBLE
        binding.controller.tvRingTempText.visibility = View.GONE
        binding.controller.speedRingView.visibility = View.GONE
        binding.controller.steamFire.visibility = View.GONE;
        binding.controller.tvSpeedText.visibility = View.GONE
        binding.controller.clSetTime.visibility = View.VISIBLE
        binding.controller.flDirection.visibility = View.GONE
        if (viewModel.displayStep()?.isTurboMode() != true) {
            binding.ivTurboView.visibility = View.GONE
        }
        setPanelViewProperty(CookSettingType.TIME_SETTING)
    }

    fun changeSpeedSettingStep() {
        binding.llWeightView.visibility = View.GONE
        binding.controller.root.visibility = View.VISIBLE
        binding.controller.tempRingView.visibility = View.INVISIBLE
        binding.controller.tvRingTempText.visibility = View.GONE
        binding.controller.steamFire.visibility = View.GONE;

        binding.controller.speedRingView.visibility = View.VISIBLE
        binding.controller.tvSpeedText.visibility = View.VISIBLE
        binding.controller.clSetTime.visibility = View.GONE
        binding.controller.flDirection.visibility = View.GONE
        if (viewModel.displayStep()?.isTurboMode() != true) {
            binding.ivTurboView.visibility = View.GONE
        }
        setPanelViewProperty(CookSettingType.SPEED_SETTING)
    }

    fun changeDirectionSettingStep() {
        binding.llWeightView.visibility = View.GONE
        binding.controller.root.visibility = View.VISIBLE
        binding.controller.tempRingView.visibility = View.INVISIBLE
        binding.controller.tvRingTempText.visibility = View.GONE
        binding.controller.steamFire.visibility = View.GONE;

        binding.controller.speedRingView.visibility = View.GONE
        binding.controller.tvSpeedText.visibility = View.GONE
        binding.controller.clSetTime.visibility = View.GONE
        binding.controller.flDirection.visibility = View.VISIBLE
        if (viewModel.displayStep()?.isTurboMode() != true) {
            binding.ivTurboView.visibility = View.GONE
        }
        setPanelViewProperty(CookSettingType.DIRECTION_SETTING)
    }

    private fun setPanelViewProperty(selectStep: CookSettingType) {
        binding.controller.apply {
            root.tag = selectStep
            viewSelectTemp.visibility = View.INVISIBLE
            viewSelectTime.visibility = View.INVISIBLE
            viewSelectSpeed.visibility = View.INVISIBLE
            viewSelectDirection.visibility = View.INVISIBLE
            tvTempValue.isSelected = false
            tvTitleTemp.isSelected = false
            tvSetTime.isSelected = false
            tvTitleTime.isSelected = false
            tvSetSpeed.isSelected = false
            tvTitleSpeed.isSelected = false
            tvSetDirection.isSelected = false
            tvTitleDirection.isSelected = false
            viewBackgroundTemp.isSelected = false
            viewBackgroundTime.isSelected = false
            viewBackgroundSpeed.isSelected = false
            viewBackgroundDirection.isSelected = false
            viewIconTemp.isSelected = false
            viewIconTime.isSelected = false
            viewIconSpeed.isSelected = false
            viewIconDirection.isSelected = false
            when (selectStep) {
                CookSettingType.TEMP_SETTING -> {
                    viewSelectTemp.visibility = View.VISIBLE
                    tvTempValue.isSelected = true
                    tvTitleTemp.isSelected = true
                    viewBackgroundTemp.isSelected = true
                    viewIconTemp.isSelected = true
                }

                CookSettingType.TIME_SETTING -> {
                    viewSelectTime.visibility = View.VISIBLE
                    tvSetTime.isSelected = true
                    tvTitleTime.isSelected = true
                    viewBackgroundTime.isSelected = true
                    viewIconTime.isSelected = true
                }

                CookSettingType.SPEED_SETTING -> {
                    viewSelectSpeed.visibility = View.VISIBLE
                    tvSetSpeed.isSelected = true
                    tvTitleSpeed.isSelected = true
                    viewBackgroundSpeed.isSelected = true
                    viewIconSpeed.isSelected = true
                }

                CookSettingType.DIRECTION_SETTING -> {
                    viewSelectDirection.visibility = View.VISIBLE
                    tvSetDirection.isSelected = true
                    tvTitleDirection.isSelected = true
                    viewBackgroundDirection.isSelected = true
                    viewIconDirection.isSelected = true
                }

                else -> {}
            }
        }
    }

    fun getSelectedTabType(): CookSettingType {
        return binding.controller.root.tag as? CookSettingType ?: CookSettingType.TEMP_SETTING
    }

    private fun showCookStepDetailDialog() {
        if (!isCookDetailDialogShow) {
            val dialogView = layoutInflater.inflate(
                R.layout.item_cook_details, binding.flCookDetails, true
            )
            val textView = dialogView.findViewById<TextView>(R.id.tv_details)
            textView.text = viewModel.getStepCombineText()
            val closeView = dialogView.findViewById<View>(R.id.iv_close)
            isCookDetailDialogShow = true
            closeView.setOnClickListener {
                isCookDetailDialogShow = false
                binding.flCookDetails.removeAllViews()
            }
        }
    }

    private val adapter = CookDetailSourceAdapter()

    private fun showCookSourceDialog() {
        if (!isCookStepDialogShow) {
            adapter.colorResId = R.color.color_333333
            val dialogView = layoutInflater.inflate(
                R.layout.item_cook_source_1, binding.flCookDetails, true
            )
            val rlView = dialogView.findViewById<RecyclerView>(R.id.rv_list)
            rlView.adapter = adapter

            val cookDetailInfo = Gson().fromJson(cookStepDetail, CookDetailInfo::class.java)
            val portionSize = Gson().fromJson(portionSizelJson, DevRecipePortionSize::class.java)

            val sourceItems = mutableListOf<CookSourceItem>()
            val originalList = mutableListOf<CookSourceItem>()
            for (recipeFood in cookDetailInfo.material) {
                val sourceItem = CookSourceItem(
                    recipeFood.foodName ?: "",
                    "${
                        BigDecimal.valueOf(recipeFood.amount ?: 0f.toDouble()).stripTrailingZeros()
                            .toPlainString()
                    } ${recipeFood.unit}"
                )
                if (recipeFood.recipePortionSizeNumber == portionSize.portionSize) {
                    sourceItems.add(sourceItem)
                }
                originalList.add(sourceItem)
            }
            if (sourceItems.isEmpty()) {
                // 防止没有任何数据显示
                sourceItems.addAll(originalList)
            }
            adapter.setNewInstance(sourceItems)
            val closeView = dialogView.findViewById<View>(R.id.iv_close)
            isCookStepDialogShow = true
            closeView.setOnClickListener {
                isCookStepDialogShow = false
                binding.flCookDetails.removeAllViews()
            }
        }
    }


    @Subscribe
    fun onDevStateEvent(event: DevStatusEvent) {
        ThreadUtils.runOnMainThread {
            runningState = event.devInfo.status.toInt()
            onDevStateChange(event.devInfo)
        }
    }

    fun playRotateAnimator(direction: Int) {
        if (rotateAnimator == null) {
            rotateAnimator = ObjectAnimator.ofFloat(
                binding.controller.viewIconDirection, View.ROTATION, 0f, 360f
            ).apply {
                duration = 2000
                repeatCount = ObjectAnimator.INFINITE
                interpolator = LinearInterpolator()
            }
        }
        if (rotateAnimator!!.isRunning) {
            if (direction == rotateAnimDir) {
                return
            } else {
                rotateAnimator?.cancel()
            }
        }
        if (direction != 0) {
            rotateAnimator?.reverse()
        } else {
            rotateAnimator?.start()
        }
        rotateAnimDir = direction
    }

    fun pauseRotateAnimator() {
        rotateAnimator?.cancel()
        binding.controller.viewIconDirection.rotation = 0f
    }

    /**
     * turbo按下事件
     */
    protected fun turboDownEvent() {
        binding.ivTurboView.setBackgroundResource(R.drawable.ic_turbo)
        startTurbo()
    }

    /**
     * turbo离开事件
     */
    protected fun turboUpEvent() {
        binding.ivTurboView.setBackgroundResource(R.drawable.ic_turbo_unselected)
        turboTimer?.cancel()
        turboTimer = null
    }

    override fun createViewBinding(inflater: LayoutInflater): ActivityFoodStep2Binding {
        return ActivityFoodStep2Binding.inflate(inflater)
    }

    override fun onDestroy() {
        super.onDestroy()
//        EventBus.getDefault().unregister(this)
        turboTimer?.cancel()
        CofarSDK.stoptWeight()
        rotateAnimator?.cancel()
        hasShowScreenSaver = false
    }

    companion object {
        const val BUTTON_TAG_START = "start"
        const val BUTTON_TAG_PAUSE = "pause"
        const val BUTTON_TAG_RESUME = "resume"
        const val BUTTON_TAG_STOP = "stop"
        const val BUTTON_TAG_RESET = "reset"
        const val BUTTON_TAG_CONFIRM = "confirm"
        const val BUTTON_TAG_CANCEL = "cancel"
        const val BUTTON_TAG_NEXT_STEP = "next"
    }
}