package com.rdiot.yx485.device.view

import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.CountDownTimer
import android.os.Handler
import android.os.Looper
import android.text.TextUtils
import androidx.lifecycle.ViewModelProvider
import com.bumptech.glide.Glide
import com.king.zxing.util.LogUtils
import com.lindroy.iosdialog.IAlertDialog
import com.rdiot.yx485.BaseActivity
import com.rdiot.yx485.R
import com.rdiot.yx485.databinding.ActivityScanDeviceBinding
import com.rdiot.yx485.device.ble.BleCtrl
import com.rdiot.yx485.device.model.BindViewModel
import com.zcolin.frame.util.ActivityUtil

class ScanDeviceActivity : BaseActivity() {
    private lateinit var bindViewModel: BindViewModel
    private var dialog: IAlertDialog? = null
    private var currentState = 0
    private var isAdded = false
    private val autoRefreshHandler = Handler(Looper.getMainLooper())
    private val REFRESH_INTERVAL: Long = 2000 // 2秒刷新间隔
    private var countDownTimer: CountDownTimer? = null

    private val checkOnlineStateRunnable: Runnable = object : Runnable {
        override fun run() {
            bindViewModel.checkOnlineState()
            autoRefreshHandler.postDelayed(this, REFRESH_INTERVAL)
        }
    }

    private val mBinding: ActivityScanDeviceBinding by lazy {
        ActivityScanDeviceBinding.inflate(
            layoutInflater
        )
    }

    companion object {
        fun newIntent(context: Context, bundle: Bundle) {
            Intent(context, ScanDeviceActivity::class.java).apply {
                putExtra("bundle", bundle)
                context.startActivity(this)
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(mBinding.root)

        initViews()
        updateUIState(currentState)
    }

    override fun onStart() {
        super.onStart()
        initData()
    }

    private fun initData() {
        bindViewModel = ViewModelProvider(this)[BindViewModel::class.java]
        bindViewModel.errorMessage.observe(this) { message ->
            showErrEventDialog(string = message)
        }

        bindViewModel.countDownTime.observe(this) {
            LogUtils.d(it.toString())
            if (it <= 0) {
                showErrEventDialog(string = "配网超时")
                BleCtrl.cancelBind()
            } else {
                mBinding.subtitleTextView.text = String.format("%sS", it)
            }
        }

        bindViewModel.onlineState.observe(this) {
            if (it) {
                updateUIState(3)
                Handler(Looper.getMainLooper()).postDelayed(object : Runnable {
                    override fun run() {
                        BleCtrl.cancelBind()
                        bindSuccess()
                    }
                }, 2000)
            }
        }

        bindViewModel.addState.observe(this) {
            if (it) {
                stopCheckDeviceOnlineState()
                showSuccessDialog()
            }
        }

        val bundle = intent.getBundleExtra("bundle")
        bundle?.let {
            val homeId = it.getString("home_id")
            val roomId = it.getString("room_id")
            var roomName = it.getString("room_name")
            val deviceName = it.getString("deviceName")
            val deviceNumber = it.getString("deviceNumber")
            val deviceTypeId = it.getString("device_type_id")
            if (TextUtils.isEmpty(homeId) || TextUtils.isEmpty(roomName) ||
                TextUtils.isEmpty(deviceNumber) || TextUtils.isEmpty(deviceTypeId)
            ) {
                showMessage("缺少必要参数，请返回重新填写")
                return
            }

            bindViewModel.homeId.set(homeId)
            bindViewModel.roomName.set(roomName)
            bindViewModel.deviceTypeId.set(deviceTypeId)
            bindViewModel.deviceCode.set(deviceNumber)

            bindViewModel.roomId.set(roomId)
            bindViewModel.deviceName.set(deviceName)

            bindViewModel.startCountDown()
            bindViewModel.isMaster = bundle.getBoolean("isMaster")

            if (bindViewModel.isMaster) {
                val bluetooth = bundle.getBoolean("bluetooth", false)
                if (bluetooth) {
                    startBindDevice(it)
                } else {
                    startCountDownTimer()
                }
                return
            }

            val subDeviceCode = it.getString("subDeviceCode")
            if (TextUtils.isEmpty(subDeviceCode)) {
                showMessage("分控设备编号不能为空")
                return
            }

            bindViewModel.subDeviceCode.set(subDeviceCode)
            startCountDownTimer()
        }
    }

    private fun startCountDownTimer() {
        countDownTimer = object : CountDownTimer(4000, 1000) {
            override fun onTick(millisUntilFinished: Long) {
                val count = (millisUntilFinished / 1000).toInt()
                LogUtils.d("onTick:$count")
                if (count == 1) {
                    updateUIState(3)
                }
            }

            override fun onFinish() {
                bindViewModel.addDeviceToRoom()
            }
        }
        countDownTimer?.start()
    }

    private fun startBindDevice(bundle: Bundle) {
        val ssid = bundle.getString("ssid")
        val pwd = bundle.getString("pwd")
        val bluetooth = bundle.getBoolean("bluetooth", false)
        val needDeviceCode = bundle.getBoolean("need_device_code", false)
        if (TextUtils.isEmpty(ssid) || TextUtils.isEmpty(pwd)) {
            showMessage("缺少必要参数，请返回重新填写")
            return
        }

        BleCtrl.autoBind(
            this,
            bindViewModel.deviceCode.get()!!,
            bindViewModel.homeId.get()!!,
            bindViewModel.roomName.get()!!,
            ssid!!,
            pwd!!,
            bindViewModel.deviceTypeId.get()!!,
            !bluetooth && needDeviceCode
        ) { e ->
            val evenString = "Step:${e.getStep()} -- Code:${e.getCode()} -- Id：${e.getId()}\n"
            LogUtils.i(evenString)
            mBinding.tvContent.append(evenString)
            if (e.getCode() == 0) {
                updateUIState(e.getStep())
            }

            if (!TextUtils.isEmpty(e.getId())) {
                bindViewModel.deviceCode.set(e.getId())
                if (bluetooth && !needDeviceCode) {
                    startCheckDeviceOnlineState()
                }
            }

            //添加成功
            if (e.getStep() == 5 && e.getCode() == 0) {
                BleCtrl.cancelBind()
                bindSuccess()
                return@autoBind
            }

            if (e.getStep() == -1 || !e.isSuccess()) {
                showErrEventDialog(e.getCode())
                BleCtrl.cancelBind()
            }
        }
    }

    private fun bindSuccess() {
        if (isAdded) {
            return
        }

        isAdded = true
        bindViewModel.addDeviceToRoom()
        bindViewModel.stopCountDown()
    }

    private fun showSuccessDialog() {
        dialog?.dismiss()
        dialog = IAlertDialog.build(this)
            .setTitle("添加成功")
            .setCancelOutside(false)
            .setShowNegButton(false)
            .setAlpha(1.0F)
            .setMessage("添加设备成功，点击确定返回列表查看")
            .setPosButtonText(R.string.got_it)
            .setPosClickListener {
                ActivityUtil.backToHome()
            }

        dialog?.isCancelable = false
        dialog?.show()
    }

    private fun showErrEventDialog(code: Int? = null, string: String? = null) {
        bindViewModel.stopCountDown()
        dialog?.dismiss()
        dialog = IAlertDialog.build(this)
            .setTitle("添加失败")
            .setCancelOutside(false)
            .setShowNegButton(false)
            .setAlpha(1.0F)
            .setPosButtonText(R.string.got_it)
            .setPosClickListener {
                finish()
            }

        code?.let {
            dialog?.setMessage(String.format("错误代码：%s", it))
        }
        string?.let {
            dialog?.setMessage(it)
        }
        dialog?.isCancelable = false
        dialog?.show()
    }

    private fun initViews() {
        isAdded = false
        mBinding.layoutTitle.btnTitleLeft.setOnClickListener { finish() }
    }

    private fun updateUIState(state: Int) {
        when (state) {
            0 -> showSearchingDevicesState()
            1 -> showNetworkMonitoringState()
            3-> showNetworkConfigState()
        }
    }

    private fun showNetworkMonitoringState() {
        bindViewModel.startCountDown()
        mBinding.titleTextView.text = "正在监测网络状态"
        Glide.with(this).load(R.drawable.gif_2).into(mBinding.imageState)
    }

    private fun showNetworkConfigState() {
        bindViewModel.startCountDown()
        mBinding.titleTextView.text = "正在为设备配网"
        Glide.with(this).load(R.drawable.gif_3).into(mBinding.imageState)
    }

    private fun showSearchingDevicesState() {
        mBinding.titleTextView.text = "正在搜索设备"
        Glide.with(this).load(R.drawable.gif_1).into(mBinding.imageState)
    }

    /**
     * 启动定时刷新
     */
    private fun startCheckDeviceOnlineState() {
        updateUIState(1)
        stopCheckDeviceOnlineState() // 先停止之前的定时任务
        autoRefreshHandler.postDelayed(checkOnlineStateRunnable, REFRESH_INTERVAL)
    }

    /**
     * 停止定时刷新
     */
    private fun stopCheckDeviceOnlineState() {
        autoRefreshHandler.removeCallbacks(checkOnlineStateRunnable)
    }

    override fun onDestroy() {
        // 停止定时刷新
        stopCheckDeviceOnlineState()
        BleCtrl.cancelBind()
        countDownTimer?.cancel()
        super.onDestroy()
    }
}