package com.develop.step.ui.cook_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 com.alibaba.android.arouter.facade.annotation.Autowired
import com.alibaba.android.arouter.launcher.ARouter
import com.develop.base.ext.updateText
import com.develop.base.util.ThreadUtils
import com.develop.common.dialog.CancelConfirmDialog
import com.develop.common.ui.CommonBVMActivity
import com.develop.common.widget.CookProgressDrawable
import com.develop.common.widget.RingControlView
import com.develop.step.CookSettingType
import com.develop.common.R
import com.develop.common.data_repo.FoodDataProvider
import com.develop.common.data_repo.db.entity.UserRecipeStepRemark
import com.develop.common.dialog.NoteEditDialog
import com.develop.common.tag.CURRENT_USER_ID
import com.develop.step.databinding.ActivityCookStepBaseBinding
import com.develop.step.viewmodel.CookStepViewModel
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.EventBus
import org.greenrobot.eventbus.Subscribe
import java.util.*

abstract class CookStepBaseActivity :
    CommonBVMActivity<ActivityCookStepBaseBinding, CookStepViewModel>() {
    @JvmField
    @Autowired(name = "number")
    var recipeNumber: String? = null

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

    @JvmField
    @Autowired(name = "isLike")
    var isLike = true

    var runningState = 0

    val cookProgressDrawable = CookProgressDrawable()
    private var turboTimer: Timer? = null

    val backRequestDialog by lazy {
        CancelConfirmDialog()
    }

    val overrideModeDialog by lazy {
        CancelConfirmDialog()
    }

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

    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 onUserWaterGear(value: Int)

    abstract fun onDevStateChange(devInfo: DevInfo)

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

    override fun createViewModel(): CookStepViewModel {
        return getViewModel(CookStepViewModel::class.java)
    }

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

    @SuppressLint("ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        hasShowScreenSaver = true
        ARouter.getInstance().inject(this)
        
        binding.viewProgress.background = cookProgressDrawable
        binding.tvTitleStep.setOnClickListener {
            showCookDetailDialog()
        }
//        binding.tvStepName.setOnClickListener {
//            showCookDetailDialog()
//        }
        binding.viewRemark.setOnClickListener {

            Log.i("dd",CURRENT_USER_ID.toString() + recipeNumber.toString() + currentStepIndex.toString());
            var data = FoodDataProvider.getUserDatabase().userInfoDao().queryUserRecipeStepRemark(
                CURRENT_USER_ID,recipeNumber.toString(),viewModel.stepIndex.toString());
            var dialog = NoteEditDialog();
            dialog.text = data?.remark
            dialog.listener = object :NoteEditDialog.OnDialogClickListener{
                override fun onComplete(remark:String) {
                    viewModel.recipe?.let {


                        if(data == null){
                            data = UserRecipeStepRemark(
                                recipeNumber = it.number.toString(),
                                stepNumber = viewModel.stepIndex.toString(),
                                userId = CURRENT_USER_ID,
                                remark = remark
                            )
                        }else{
                            data!!.remark = remark;
                        }

                        FoodDataProvider.getUserDatabase().userInfoDao().insertUserRecipeStepRemark(
                            data!!
                        );


                    }

                }

                override fun onClear() {
                }

            };
            dialog.showDialog(supportFragmentManager, "NoteEditDialog")

        }
        binding.ivNextStep.setOnClickListener {
            clickNextStep()
            viewModel.stepUiData.doingModify = false
        }
        binding.ivPrevStep.setOnClickListener {
            clickPrevStep()
            viewModel.stepUiData.doingModify = false
        }
        binding.controller.clCookTemp.setOnClickListener {
            changeTempSettingPanel()
        }
        binding.controller.clCookTime.setOnClickListener {
            changeTimeSettingPanel()
        }
        binding.controller.clCookSpeed.setOnClickListener {
            changeSpeedSettingStep()
        }
        binding.controller.clCookDirection.setOnClickListener {
            changeDirectionSettingStep()
        }
        binding.controller.clCookWater.setOnClickListener{
            changeWaterGearSettingStep()
        }
        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.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)
                }
            }

            waterRingView.setRange(0f, 2f)
            speedRingView.updateProgress(0)
            waterRingView.onRingViewListener = object : RingControlView.OnRingViewListener {
                override fun onProgressChange(progress: Int) {
                    viewModel.stepUiData.doingModify = true
                    onUserWaterGear(progress)
                }
            }

        }
        binding.ivTurboView.setOnTouchListener { view, motionEvent ->
            when (motionEvent.action) {
                MotionEvent.ACTION_DOWN -> {
                    turboDownEvent()
                }
                MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_UP -> {
                    turboUpEvent()
                }
            }
            true
        }
        configureDirection()
    }

    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.rotation = 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.rotation = 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.controller.tempRingView.visibility = View.GONE
        binding.controller.tvRingTempText.visibility = View.GONE
        binding.ivTurboView.visibility = View.VISIBLE
    }

    fun changeTempSettingPanel() {
        binding.controller.waterRingView.visibility = View.GONE
        binding.controller.waterSprayShow.visibility = View.GONE
        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
        }
        setPanelViewProperty(CookSettingType.TEMP_SETTING)
    }

    fun changeTimeSettingPanel() {
        binding.controller.waterRingView.visibility = View.GONE
        binding.controller.waterSprayShow.visibility = View.GONE
        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.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.controller.waterRingView.visibility = View.GONE
        binding.controller.waterSprayShow.visibility = View.GONE
        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.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 changeWaterGearSettingStep() {
        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.tvSpeedText.visibility = View.GONE
        binding.controller.clSetTime.visibility = View.GONE
        binding.controller.flDirection.visibility = View.GONE

        binding.controller.waterRingView.visibility = View.VISIBLE
        binding.controller.waterSprayShow.visibility = View.VISIBLE

        if (viewModel.displayStep()?.isTurboMode() != true) {
            binding.ivTurboView.visibility = View.GONE
        }
        setPanelViewProperty(CookSettingType.WATER_SPRY)
    }

    fun changeDirectionSettingStep() {
        binding.controller.waterRingView.visibility = View.GONE
        binding.controller.waterSprayShow.visibility = View.GONE
        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.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
            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
            tvCookingTempTarget.isSelected = false
            tvCookingTimeTarget.isSelected = false
            clCookWater.upSelectedView(false)
            when (selectStep) {
                CookSettingType.TEMP_SETTING -> {
                    tvCookingTempTarget.isSelected = true
                    tvTempValue.isSelected = true
                    tvTitleTemp.isSelected = true
                    viewBackgroundTemp.isSelected = true
                    viewIconTemp.isSelected = true
                }
                CookSettingType.TIME_SETTING -> {
                    tvCookingTimeTarget.isSelected = true
                    tvSetTime.isSelected = true
                    tvTitleTime.isSelected = true
                    viewBackgroundTime.isSelected = true
                    viewIconTime.isSelected = true
                }
                CookSettingType.SPEED_SETTING -> {
                    tvSetSpeed.isSelected = true
                    tvTitleSpeed.isSelected = true
                    viewBackgroundSpeed.isSelected = true
                    viewIconSpeed.isSelected = true
                }
                CookSettingType.DIRECTION_SETTING -> {
                    tvSetDirection.isSelected = true
                    tvTitleDirection.isSelected = true
                    viewBackgroundDirection.isSelected = true
                    viewIconDirection.isSelected = true
                }
                CookSettingType.WATER_SPRY -> {
                clCookWater.upSelectedView(true)
             }
                else -> {}
            }
        }
    }

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

    fun setStepTextIconEnable(enable: Boolean) {
        binding.controller.apply {
            tvTempValue.isEnabled = enable
            viewIconTemp.isEnabled = enable
            tvTitleTemp.isEnabled = enable
            tvCookingTempTarget.isEnabled = enable
            tvSetTime.isEnabled = enable
            viewIconTime.isEnabled = enable
            tvTitleTime.isEnabled = enable
            tvCookingTimeTarget.isEnabled = enable
            tvSetSpeed.isEnabled = false
            viewIconSpeed.isEnabled = false
            tvTitleSpeed.isEnabled = false
            tvSetDirection.isEnabled = false
            viewIconDirection.isEnabled = false
            tvTitleDirection.isEnabled = false
        }
    }

    private fun showCookDetailDialog() {
        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()
            }
        }
    }

    @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 onDestroy() {
        super.onDestroy()
        
        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"
    }
}