package com.dlc.eboard.ui

import android.app.AlertDialog
import android.content.ComponentName
import android.content.Intent
import android.content.ServiceConnection
import android.graphics.Color
import android.os.Bundle
import android.os.Handler
import android.os.IBinder
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.ImageView
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.dlc.eboard.BuildConfig
import com.dlc.eboard.LabApp
import com.dlc.eboard.R
import com.dlc.eboard.common.AuthTypeConfig
import com.dlc.eboard.common.CommonUtils
import com.dlc.eboard.common.SensorEnum
import com.dlc.eboard.databinding.ActivityHomeBinding
import com.dlc.eboard.databinding.ItemHomePersonFlipperBinding
import com.dlc.eboard.event.OnlineUserEvent
import com.dlc.eboard.finger.FingerHelper
import com.dlc.eboard.finger.OnFingerListener
import com.dlc.eboard.mqtt.AudioService
import com.dlc.eboard.mqtt.MqttService
import com.dlc.eboard.mqtt.entity.BulletinBoardEntity
import com.dlc.eboard.mqtt.event.*
import com.dlc.eboard.serial.OnSerialScanListener
import com.dlc.eboard.serial.SerialPortHelper
import com.dlc.eboard.sp.DeviceSp
import com.dlc.eboard.ui.auth.*
import com.dlc.eboard.ui.common.BaseCountDownActivity
import com.dlc.eboard.ui.dialog.WaringDialog
import com.dlc.eboard.ui.home.AccessPersonFragment
import com.dlc.eboard.ui.home.HomeFragmentCallback
import com.dlc.eboard.ui.home.LabBasicFragment
import com.dlc.eboard.ui.lib.LabDescActivity
import com.dlc.eboard.ui.rule.SafetyRegulationActivity
import com.dlc.eboard.ui.settings.PasswordDialog
import com.dlc.eboard.ui.settings.SettingsActivity
import com.dlc.eboard.ui.widget.ItemBoardView
import com.dlc.eboard.ui.widget.LooperLayoutManager
import com.dlc.eboard.ui.widget.NavViewCompat
import com.dlc.eboard.ui.widget.TitleBar
import com.dlc.laboratory.ui.msds.ExInstructionActivity
import com.github.mikephil.charting.components.Description
import com.github.mikephil.charting.components.Legend
import com.github.mikephil.charting.components.LegendEntry
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.PieData
import com.github.mikephil.charting.data.PieDataSet
import com.github.mikephil.charting.data.PieEntry
import com.github.mikephil.charting.highlight.Highlight
import com.github.mikephil.charting.listener.OnChartValueSelectedListener
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.rc.core.log.RcLog
import com.rc.core.ui.widget.decoration.NoLastLineItemDecoration
import com.rc.core.util.ApkUpdater
import com.rc.core.util.DeviceUtils
import com.rc.core.util.FastClickDelegate
import com.rc.httpcore.client.ApiRepository
import com.rc.httpcore.vo.GroupNameBean
import com.rc.httpcore.vo.response.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.json.JSONObject
import java.util.*
import kotlin.collections.HashMap
import kotlin.collections.HashSet
import kotlin.collections.set


/**
 * 主页
 *
 * @author ReiChin_
 */
class HomeActivity :
    BaseCountDownActivity<ActivityHomeBinding>(),
    HomeFragmentCallback {

    companion object {
        private const val SENSOR_SPLASH_TIME = 3000L // 传感器面板1.5s自动滚动
    }

    private var isFragment = false
    private lateinit var bFragments: BlankFragment
    private var isFragmentVisible = true

    override val mTitleBar: TitleBar by lazy { viewBinding.titleBar }
    override val mNavView: NavViewCompat? = null

    private val mBulletinBoardAdapter = HomeBoardAdapter()
    private lateinit var labBasicFragment: LabBasicFragment

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        bindService(Intent(this, MqttService::class.java), mConnection, BIND_AUTO_CREATE)
        startService(Intent(this, HeartService::class.java))
        bindService(Intent(this, AudioService::class.java), mAudioConnection, BIND_AUTO_CREATE)
        mSerialPortHelper.bindService()
//        mFingerHelper = generateFingerHelper()
//        lifecycle.addObserver(mFingerHelper)
    }

    override fun onDestroy() {
        unbindService(mConnection)
        stopService(Intent(this, HeartService::class.java))
        unbindService(mAudioConnection)
        mSerialPortHelper.unbindService()
        super.onDestroy()
//        lifecycle.removeObserver(mFingerHelper)
        handler.removeCallbacks(runnable)
    }

    private val mConnection: ServiceConnection = object : ServiceConnection {

        override fun onServiceConnected(name: ComponentName, service: IBinder) {
            LabApp.sLabConfig?.let { config ->
                service as MqttService.MqttBinder
                service.initMqtt(config.labId)
            }
        }

        override fun onServiceDisconnected(name: ComponentName) {
        }
    }

    private var mAudioBinder: AudioService.AudioBinder? = null

    private val mAudioConnection: ServiceConnection = object : ServiceConnection {

        override fun onServiceConnected(name: ComponentName, service: IBinder) {
            mAudioBinder = service as AudioService.AudioBinder
        }

        override fun onServiceDisconnected(name: ComponentName) {
        }
    }

    override fun createViewBinding() = ActivityHomeBinding.inflate(layoutInflater)

    override fun initViews(savedInstanceState: Bundle?) {
        val transaction = supportFragmentManager.beginTransaction()
        labBasicFragment = LabBasicFragment.newInstance()
        transaction.add(
            R.id.container,
            labBasicFragment!!,
            LabBasicFragment.TAG
        )
        transaction.commitAllowingStateLoss()
//        transaction.commit()

        viewBinding.bulletinBoardView.layoutManager = LooperLayoutManager(RecyclerView.HORIZONTAL)
        val decor = NoLastLineItemDecoration(this, DividerItemDecoration.HORIZONTAL)
        decor.setDrawable(ContextCompat.getDrawable(this, R.drawable.shape_item_divider_middle)!!)
        viewBinding.bulletinBoardView.addItemDecoration(decor)
        viewBinding.bulletinBoardView.adapter = mBulletinBoardAdapter


//        viewBinding.rightView.setOnClickListener {
//           viewBinding.container.visibility=View.GONE
//        }


    }

    override fun initListener() {
        viewBinding.titleBar.setTitleListener(this)
        viewBinding.titleBar.setOnLongClickListener {
            PasswordDialog(this) {
                val intent = Intent(this, SettingsActivity::class.java)
                startActivity(intent)
            }.show()
            true
        }
//        // 值班人员
//        viewBinding.dutyExpand.setOnClickListener(FastClickDelegate {
//            if (null == LabApp.sLabConfig) return@FastClickDelegate
//
//            val fragment = supportFragmentManager.findFragmentByTag(DutyPersonFragment.TAG)
//                    as? DutyPersonFragment ?: DutyPersonFragment()
//            fragment.arguments = Bundle().apply {
//                putString("labId", LabApp.sLabConfig!!.labId)
//            }
//            supportFragmentManager.beginTransaction().apply {
////                setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
//                setCustomAnimations(R.anim.from_right, 0, 0, R.anim.out_right)
//                replace(R.id.container, fragment, DutyPersonFragment.TAG)
//                addToBackStack(null)
//                commit()
//            }
//            switchPersonPanel(View.GONE)
//        })

//        // 实验人员
//        viewBinding.experimentExpand.setOnClickListener(FastClickDelegate {
//            if (null == LabApp.sLabConfig) return@FastClickDelegate
//
//            val fragment = supportFragmentManager.findFragmentByTag(AccessPersonFragment.TAG_EXPERIMENT)
//                    as? AccessPersonFragment ?: AccessPersonFragment()
//            fragment.arguments = Bundle().apply {
//                putInt("type", AccessPersonFragment.TYPE_EXPERIMENT)
//                putString("labId", LabApp.sLabConfig!!.labId)
//            }
//            supportFragmentManager.beginTransaction().apply {
////                setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
//                setCustomAnimations(R.anim.from_right, 0, 0, R.anim.out_right)
//                replace(R.id.container, fragment, AccessPersonFragment.TAG_EXPERIMENT)
//                addToBackStack(null)
//                commit()
//            }
//            switchPersonPanel(View.GONE)
//        })

//        // 准入人员
//        viewBinding.accessExpand.setOnClickListener(FastClickDelegate {
//            if (null == LabApp.sLabConfig) return@FastClickDelegate
//
//            val fragment = supportFragmentManager.findFragmentByTag(AccessPersonFragment.TAG_ACCESS)
//                    as? AccessPersonFragment ?: AccessPersonFragment()
//            fragment.arguments = Bundle().apply {
//                putInt("type", AccessPersonFragment.TYPE_ACCESS)
//                putString("labId", LabApp.sLabConfig!!.labId)
//            }
//            supportFragmentManager.beginTransaction().apply {
////                setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
//                setCustomAnimations(R.anim.from_right, 0, 0, R.anim.out_right)
////                setCustomAnimations(R.anim.from_right, R.anim.out_right)
//                replace(R.id.container, fragment, AccessPersonFragment.TAG_ACCESS)
//                addToBackStack(null)
//                commit()
//            }
//            switchPersonPanel(View.GONE)
//        })

        //MSDS
        viewBinding.learnMaterial.setOnClickListener {
            val intent = Intent(this, ExInstructionActivity::class.java)
            startActivity(intent)
        }

        // 规章制度
        viewBinding.safetyRegulation.setOnClickListener(FastClickDelegate {
            val intent = Intent(this, SafetyRegulationActivity::class.java)
            startActivity(intent)
        })

        viewBinding.dutyExpandGons.setOnClickListener {
            toggleFragmentVisibility()


        }
        // 实验室简介
        viewBinding.labDesc.setOnClickListener(FastClickDelegate {
            startActivity(Intent(this, LabDescActivity::class.java))
        })
        // 身份验证
        viewBinding.accessVerify.setOnClickListener(FastClickDelegate {
            val authType = LabApp.sLabConfig?.authType ?: return@FastClickDelegate
            when (authType) {
                AuthTypeConfig.FINGER.type -> {
                    val intent = Intent(this, FingerAuthActivity::class.java)
                    startActivity(intent)
                }
                AuthTypeConfig.FOUR_CHOICE.type -> {
                    val intent = Intent(this, FourChoiceAuthActivity::class.java)
                    startActivity(intent)
                }
                AuthTypeConfig.FACE_OR_FINGER.type -> {
                    val intent = Intent(this, TwoChoiceAuthActivity::class.java)
                    startActivity(intent)
                }
                AuthTypeConfig.CARD_PASSWORD.type,
                AuthTypeConfig.FACE_PASSWORD.type,
                AuthTypeConfig.FACE_CARD.type,
                -> {
                    val intent = Intent(this, DualAuthActivity::class.java)
                    startActivity(intent)
                }
            }
        })


    }

    private val handler = Handler()
    private val runnable = object : Runnable {
        override fun run() {
            // 在这里编写需要执行的刷新任务代码
            queryLabConfig()  //更新当前管理员信息到本地 后面都会用到 不可删除

            queryBulletinBoard() //获取的温度 湿度等数据
            queryNoticeMsgList()
            getGroupNameList()//加载气瓶信息

            queryPerson()//有本地存储的过程 必须在最后一个调用
            handler.postDelayed(this, 5 * 60 * 1000)
//            handler.postDelayed(this, 6000)
        }
    }
    private fun queryLabConfig() {
        showLoading("加载中...")
        val disposable = ApiRepository.queryLabConfig(CommonUtils.getAndroidId())
            .subscribe({ data ->
                LabApp.sLabConfig = data
                queryLaboratoryInfo("1" == data.isStart, data.labId)
            }, { throwable ->
                dismissLoading()
                throwable.printStackTrace()
                showNetError(throwable)
            })
        addDisposable(disposable)
    }

    private fun queryLaboratoryInfo(openEBoard: Boolean, labId: String) {
        val id = if (openEBoard) labId else CommonUtils.getAndroidId()
        val disposable = ApiRepository.laboratoryInfo(openEBoard, id)
            .subscribe({ data ->
                dismissLoading()
                DeviceSp.saveLaboratoryVo(this, data)
            }, { throwable ->
                dismissLoading()
                throwable.printStackTrace()
                showNetError(throwable)
            })
        addDisposable(disposable)
    }

    override fun initData() {
        if (null == LabApp.sLabConfig) {
            showToast("暂无实验室信息，即将重新获取")
            CommonUtils.restartApp(this)
            return
        }
        viewBinding.titleBar.setTitleInfoFromSp()

        queryBulletinBoard()
        queryPerson()
        queryNoticeMsgList()
        getGroupNameList()//加载气瓶信息

        handler.postDelayed(runnable, 2 * 60 * 1000)
//        handler.postDelayed(runnable, 6000)

    }

    //http://192.168.1.17:8080/airbottle/stock/groupName?subjectId=241 get
    //获取气瓶信息列表
    private fun getGroupNameList() {
        val disposable = ApiRepository.getGroupNameList(LabApp.sLabConfig!!.labId)
            .subscribe({ response ->
                if (response != null) {
                    upPieChartView(response)
                }
            }, { throwable ->
                showNetError(throwable)
            })
        addDisposable(disposable)

    }


    private fun upPieChartView(response: List<GroupNameBean>) {

        val pieChart = viewBinding.mPieChart
        if (response != null) {
            pieChart.visibility = View.VISIBLE
        } else {
            pieChart.visibility = View.GONE
            return
        }

        val legend: Legend = pieChart.legend
        legend.isEnabled = false // 启用图例
        legend.textSize = 8f // 设置标题文字大小
        val description: Description = pieChart.description
        description.isEnabled = false
        // 准备数据
        val entries = ArrayList<PieEntry>()
        // 设置数据集
        val dataSet = PieDataSet(entries, " ")
//        //可用颜色集合
        val colorList = listOf(
            Color.parseColor("#1e2c95"), Color.parseColor("#ed5555"), Color.parseColor("#ffa200"),
            Color.parseColor("#02a319"), Color.parseColor("#078dff")
        )

        val colorListBean = mutableListOf<Int>()//实际使用颜色集合  进行动态添加

        response.forEachIndexed { index, item ->
            entries.add(PieEntry(item.ratio.toFloat(), "${item.gasName}").apply { data = index })
            colorListBean.add(colorList[index])
        }

        dataSet.setDrawIcons(false)
        dataSet.setDrawValues(false)
        dataSet.colors = colorListBean
        dataSet.valueTextSize = 9f // 设置饼图数值文字大小
        pieChart.setEntryLabelTextSize(9f) // 设置饼图条目文字大小
        // 设置 PieData
        val data = PieData(dataSet)
        pieChart.data = data
        pieChart.invalidate() // 刷新图表显示

        // 禁止描述项显示
        dataSet.setDrawValues(false)

        // 设置饼形图为实心模式
        pieChart.isDrawHoleEnabled = false

        // 其他配置和动画设置...
        pieChart.setTouchEnabled(true) // 启用触摸事件
        pieChart.description.isEnabled = false
        // 添加点击事件
        pieChart.setOnChartValueSelectedListener(object : OnChartValueSelectedListener {
            override fun onValueSelected(e: Entry?, h: Highlight?) {
                // 点击扇形时的操作
                if (e is PieEntry) {
                    //e.label当前点击的名称
//                    getListByName(e.label)
                    if (e.label != null) {
                        val index = (e as? PieEntry)?.data as? Int
                        RcLog.info("=========当前点击得${response[index!!].gasName}")
                        RcLog.info("=========当前点击得${response[index!!].remark}")
                        var remark: String? = null
                        var flg: String? = null
                        if (response[index!!].flg != null) {
                            remark = response[index!!].remark
                            flg = response[index!!].flg
                        }
                        viewBinding.viewTwo.visibility = View.VISIBLE
                        viewBinding.dutyExpandGons.visibility = View.VISIBLE
                        hideFirstFragment()
                        if (isFragment) {
//                            // 如果Fragment已经加载过，则从FragmentManager中获取已有的Fragment实例
//                                bFragments =
//                                    supportFragmentManager.findFragmentById(R.id.container) as BlankFragment
                            supportFragmentManager.beginTransaction()
                                .show(bFragments!!)
                                .commit()
                            bFragments.updateData(e.label, remark, flg)
                        } else {
                            isFragment = true
                            bFragments = supportFragmentManager.findFragmentByTag(BlankFragment.TAG)
                                    as? BlankFragment ?: BlankFragment()

                            bFragments.arguments = Bundle().apply {
                                putString("gasName", e.label)
                                putString("remark", remark)
                                putString("flg", flg)
                            }

                            supportFragmentManager.beginTransaction().apply {
                                setCustomAnimations(R.anim.from_right, 0, 0, R.anim.out_right)
                                replace(R.id.container, bFragments, BlankFragment.TAG)
                                addToBackStack(null)

                                commit()
                            }
//                                switchPersonPanel(View.GONE)
                        }

                    }

                }
            }

            override fun onNothingSelected() {
                // 没有选中扇形时的操作
            }
        })
        pieChart.invalidate()
    }

    // 切换 Fragment 的显示或隐藏状态
    private fun toggleFragmentVisibility() {
        val fragments = supportFragmentManager.fragments
        RcLog.info("==========当前有几个============${fragments.size}")
        viewBinding.viewTwo.visibility = View.GONE
        viewBinding.dutyExpandGons.visibility = View.GONE
        hideSecondFragment()
        val transaction = supportFragmentManager.beginTransaction()
        labBasicFragment = LabBasicFragment.newInstance()
        transaction.add(
            R.id.container,
            labBasicFragment!!,
            LabBasicFragment.TAG
        )
        transaction.commit()
//        loadFirstFragment()
    }

    // 隐藏第一个 Fragment
    fun hideFirstFragment() {
        if (labBasicFragment != null) {
            supportFragmentManager.beginTransaction()
                .hide(labBasicFragment)
                .commit()
        }
    }

    private fun loadFirstFragment() {

        supportFragmentManager.beginTransaction()
            .show(labBasicFragment)
            .commit()
    }

    // 隐藏第二个 Fragment
    private fun hideSecondFragment() {
        if (bFragments != null) {
            supportFragmentManager.beginTransaction()
                .hide(bFragments)
                .commit()
        }
    }


    // 显示指定的 Fragment，并隐藏其他 Fragment
    fun showFragments(fragmentToShow: Fragment) {
        val fragmentManager = supportFragmentManager
        val fragmentTransaction = fragmentManager.beginTransaction()
        for (fragment in fragmentManager.fragments) {
            if (fragment == fragmentToShow) {
                fragmentTransaction.show(fragment)
            } else {
                fragmentTransaction.hide(fragment)
            }
        }
        fragmentTransaction.commit()
    }


    private fun queryNoticeMsgList() {
        val disposable = ApiRepository.newMsgGroup(LabApp.sLabConfig!!.labId)
            .subscribe({ response ->
                LabApp.sNoticeList = response
                viewBinding.titleBar.updateNotice(response)
            }, { throwable ->
                throwable.printStackTrace()
                showNetError(throwable)
            })
        addDisposable(disposable)
    }

    private var mHomeRightResp: HomeRightResp? = null

    private fun queryPerson() {
        RcLog.info("=====================当前请求的id${LabApp.sLabConfig!!.labId}")
        val disposable = ApiRepository.homeRightInfo(LabApp.sLabConfig!!.labId)
            .subscribe({ response ->
                dismissLoading()
                mHomeRightResp = response
                dispatchLabPerson(response)
            }, { throwable ->
                dismissLoading()
                mHomeRightResp = null
                showNetError(throwable)
                throwable.printStackTrace()
            })
        addDisposable(disposable)
    }
    private fun dispatchLabPerson(data: HomeRightResp) {
        var laboratoryVo = DeviceSp.loadLaboratoryVo(this)
        data.dutyUserTwo.add(laboratoryVo)
        // 值班人员
//        val dutyAdapter = PersonFlipperAdapter(1, data.dutyUser)
        val dutyAdapter = PersonFlipperAdapterTwo(1, data.dutyUserTwo)

        viewBinding.dutyPerson.adapter = dutyAdapter
        viewBinding.dutyPerson.flipInterval = 3000
        viewBinding.dutyPerson.setInAnimation(this, R.animator.anim_in)
        viewBinding.dutyPerson.setOutAnimation(this, R.animator.anim_out)
        if (!data.dutyUser.isNullOrEmpty()) {
            viewBinding.dutyPerson.startFlipping()
        }

        if (dutyAdapter!=null){
            dutyAdapter!!.notifyDataSetChanged()
        }
//        // 实验人员
//        val experimentAdapter = ExperimentPersonAdapter()
//        viewBinding.experimentPerson.layoutManager = LooperLayoutManager(RecyclerView.VERTICAL)
//        viewBinding.experimentPerson.adapter = experimentAdapter
//        experimentAdapter.setNewInstance(data.tentativeUser)
//        if (!data.tentativeUser.isNullOrEmpty()) {
//            viewBinding.experimentPerson.initTimer(5, data.tentativeUser.size)
//            viewBinding.experimentPerson.startAuto(SENSOR_SPLASH_TIME)
//        } else {
//            experimentAdapter.setEmptyView(R.layout.view_list_empty)
//        }

        // 准入人员
//        val accessAdapter = PersonFlipperAdapter(2, data.securityUser)
//        viewBinding.accessPerson.adapter = accessAdapter
//        viewBinding.accessPerson.flipInterval = 3000
//        viewBinding.accessPerson.setInAnimation(this, R.animator.anim_in)
//        viewBinding.accessPerson.setOutAnimation(this, R.animator.anim_out)
//        if (!data.securityUser.isNullOrEmpty()) {
//            viewBinding.accessPerson.startFlipping()
//        }
    }

    private fun queryBulletinBoard() {
        showLoading("加载中...")
        val disposable = ApiRepository.functionList(LabApp.sLabConfig!!.labId)
            .subscribe({ data ->
                dismissLoading()
                mBulletinBoardAdapter.setNewInstance(data.toMutableList())
                viewBinding.bulletinBoardView.initTimer(4, data.size)
                viewBinding.bulletinBoardView.startAuto(SENSOR_SPLASH_TIME)
                if (data.isNullOrEmpty()) {
                    mBulletinBoardAdapter.setEmptyView(R.layout.view_list_empty)
                }
                if (mBulletinBoardAdapter!=null){
                    mBulletinBoardAdapter.data=data.toMutableList()
                    mBulletinBoardAdapter.notifyDataSetChanged()
                }
                queryWarning()
            }, { throwable ->
                dismissLoading()
                throwable.printStackTrace()
                showNetError(throwable)
                mBulletinBoardAdapter.setEmptyView(R.layout.view_list_empty)
            })
        addDisposable(disposable)
    }

    private fun queryWarning() {
        val disposable = ApiRepository.warnList(LabApp.sLabConfig!!.labId)
            .subscribe({ data ->
                mBulletinBoardAdapter.updateWaringValue(data)
            }, { throwable ->
                throwable.printStackTrace()
                showNetError(throwable)
            })
        addDisposable(disposable)
    }

    private fun switchPersonPanel(visibility: Int) {
        viewBinding.dutyExpandGroup.visibility = visibility
//        viewBinding.experimentExpandGroup.visibility = visibility
        viewBinding.accessExpandGroup.visibility = visibility
    }

    override fun closePersonPanel() {
        switchPersonPanel(View.VISIBLE)
    }

    override fun onBackPressed() {
        if (supportFragmentManager.backStackEntryCount >= 1) {
            supportFragmentManager.popBackStack()
            closePersonPanel()
        } else {
            super.onBackPressed()
        }
    }

    override fun onStop() {
        backCountDownFinish()
        super.onStop()
    }

    override fun enabledBackCountDown() = true

    override fun backCountDownFinish() {
//        // 显示LabBasicFragment
//        if (supportFragmentManager.backStackEntryCount >= 1) {
//            supportFragmentManager.popBackStack()
//            closePersonPanel()
//        }
    }

    private fun generateFingerHelper(): FingerHelper {
        return FingerHelper(object : OnFingerListener {
            override fun showToast(message: String) {
                if (isFinishing || !mFingerEnabled) return
                if ("设备忙" == message) {
                    viewBinding.titleBar.postDelayed({
                        if (!isFinishing && mFingerEnabled) mFingerHelper.verify()
                    }, 1000)
                } else {
                    this@HomeActivity.showToast(message)
                }
            }

            override fun onMatchSuccess(userVo: UserFingerVo): Boolean {
                if (isFinishing || !mFingerEnabled) return false
                onAuthSuccess(AuthType.FINGER, userVo)
                return true
            }

            override fun onMatchFailure(message: String) {
                if (isFinishing || !mFingerEnabled) return
                showMatchErrDialog(message)
            }

            override fun loopMatch() {
                if (isFinishing || !mFingerEnabled) return
                mFingerHelper.verify()
            }
        })
    }

    private lateinit var mFingerHelper: FingerHelper

    private var mFingerEnabled = false

    private fun showMatchErrDialog(message: String) {
        AlertDialog.Builder(this)
            .setTitle("提示")
            .setMessage(message)
            .setCancelable(false)
            .setPositiveButton("重新验证") { _, _ ->
                mFingerHelper.verify()
            }.show()
    }

    override fun onResume() {
        // 刷卡+门禁
        mSerialPortHelper.onResume()

//        // 5s后开始验证指纹
//        viewBinding.titleBar.postDelayed({
//            mFingerHelper.lazyVerify()
//        }, 1000)
        mFingerEnabled = true
        super.onResume()
    }

    override fun onPause() {
        // 刷卡+门禁
        mSerialPortHelper.onPause()

        // 指纹
        mFingerEnabled = false
        super.onPause()
    }

    override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
        mSerialPortHelper.dispatchKeyEvent(event)
        return super.dispatchKeyEvent(event)
    }

    private val mSerialPortHelper by lazy {
        SerialPortHelper(this, object : OnSerialScanListener {
            override fun dispatchScanEvent(type: OnSerialScanListener.ScanType, content: String) {
                // 刷卡开门
                dispatchReadCardResult(content)
            }
        })
    }

    private fun dispatchReadCardResult(username: String) {
        showLoading()
        val disposable = ApiRepository.getCardIsOpen(LabApp.sLabConfig!!.labId, username)
            .subscribe({ userVo ->
                dismissLoading()
                onAuthSuccess(AuthType.CARD, userVo)
            }, { throwable ->
                dismissLoading()
                showNetError(throwable)
                throwable.printStackTrace()
            })
        addDisposable(disposable)
    }

    private fun onAuthSuccess(authType: AuthType, userVo: UserVo) {
        RcLog.info("HomeActivity#onAuthSuccess() authType=${authType}, configAuthType=${LabApp.sLabConfig?.authType}, userVo=${userVo}")
        // 在未登录首页验证成功后，判断用户是否有开门权限，登录+开门
        val configAuthType = LabApp.sLabConfig?.authType ?: return
        when (configAuthType) {
            AuthTypeConfig.FINGER.type,
            AuthTypeConfig.FACE_OR_FINGER.type,
            -> {
                if (AuthType.FINGER == authType) {
                    openDoor(userVo)
                }
            }
            AuthTypeConfig.FOUR_CHOICE.type -> {
                openDoor(userVo)
            }
            AuthTypeConfig.CARD_PASSWORD.type -> {
                if (AuthType.CARD == authType) {
                    // 进入密码验证
                    val intent = Intent(this, DualAuthActivity::class.java)
                    intent.putExtra("card_auth", true)
                    intent.putExtra("user", userVo)
                    startActivity(intent)
                }
            }
        }
    }

    private fun openDoor(userVo: UserVo) {
        LabApp.sUserVo = userVo
        val intent = Intent(this, MainActivity::class.java)
        startActivity(intent)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onUpdateEventEvent(event: UpdateEvent) {
        if (CommonUtils.stringParseInt(event.data.version) > DeviceUtils.getVersionCode(this)) {
            // 显示版本更新
            downloadApk(event.data.apkUploadFile)
        }
    }

    private var apkDownloading = false

    private fun downloadApk(downloadUrl: String) {
        if (apkDownloading) return
        apkDownloading = true
        callApkUpdateApi("2")
        ApkUpdater(applicationContext, BuildConfig.APPLICATION_ID, callback = object :
            ApkUpdater.DownloadCallback {
            override fun onProgress(progress: Int) {
            }

            override fun onFailed(errMsg: String?) {
                apkDownloading = false
                callApkUpdateApi("0")
            }

            override fun onSuccess(apkFile: String) {
                apkDownloading = false
                callApkUpdateApi("1")
            }

        }).downloadApk(downloadUrl)
    }

    /*
     * state 0:升级失败; 1:升级成功; 2:升级中
     */
    private fun callApkUpdateApi(state: String) {
        val disposable = ApiRepository.onepcApkUpdate(CommonUtils.getAndroidId(), state)
            .subscribe({ }, { })
        addDisposable(disposable)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onBulletinBoardEvent(event: BulletinBoardEvent) {
        mBulletinBoardAdapter.updateSensorValue(event.data)
    }

    private var mWaringDialog: WaringDialog? = null

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onWarningEvent(event: WarningEvent) {
        if (null == mWaringDialog) {
            if (!event.data.isNullOrEmpty()) {
                mWaringDialog = WaringDialog(this, event.data).apply {
                    setOnDismissListener {
                        mWaringDialog = null
                    }
                }
                mWaringDialog!!.show()
            }
        } else {
            if (event.data.isNullOrEmpty()) {
                mWaringDialog!!.dismiss()
            } else {
                mWaringDialog!!.updateWaringValue(event.data)
            }
        }

        mBulletinBoardAdapter.updateWaringValue(event.data)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onEmergencyEvent(event: EmergencyEvent) {
        when (event.type) {
            1 -> textParseVideo(event.data)
            2 -> mAudioBinder?.startPlayer(event.data)
        }
    }

    private fun textParseVideo(text: String?) {
        if (text.isNullOrEmpty()) return

        showLoading()
        val disposable = ApiRepository.textParseVideo(text)
            .subscribe({ data ->
                dismissLoading()
                mAudioBinder?.startPlayer(data.url)
            }, { throwable ->
                dismissLoading()
                throwable.printStackTrace()
                showNetError(throwable)
            })
        addDisposable(disposable)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onLabInfoEvent(event: LabInfoEvent) {
        // {"msg":"5","sendDate":"2023-04-13 13:17:39"}
        if (event.message.isEmpty()) return
        try {
            LabApp.sLabConfig?.let { labConfig ->
                val authType = JSONObject(event.message).optString("msg", labConfig.authType)
                labConfig.authType = authType
            }
        } catch (e: Exception) {
            RcLog.info("解析异常")
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onOnlineUserEvent(event: OnlineUserEvent) {
        queryPerson()
    }


}


private class HomeBoardAdapter :
    BaseQuickAdapter<LabBulletinBoardVo, BaseViewHolder>(R.layout.item_home_board) {

    private val mValueMap = HashMap<String, BoardValue>()
    private val mWarningSet = HashSet<String>()

    private val mSensorMap = HashMap<String, SensorEnum>().apply {
        SensorEnum.values().forEach {
            put(it.funNum, it)
        }
    }

    private fun goneSensor(funNum: String?): Boolean {
        return SensorEnum.FIRE.funNum == funNum
    }

    override fun setNewInstance(list: MutableList<LabBulletinBoardVo>?) {
        val newlyList = list?.filter { !goneSensor(it.funNum) }

        if (null != newlyList) {
            mValueMap.clear()
            newlyList.forEach {
                mValueMap[it.funNum] = BoardValue(it.`val`, it.unit, it.formatVal)
            }
        }
        super.setNewInstance(newlyList?.toMutableList())
    }

    fun updateSensorValue(data: BulletinBoardEntity.Data?) {
        val newlyList = data?.functionStatuses?.filter { !goneSensor(it.funNum) }

        var valueChanged = mValueMap.size != newlyList?.size
        newlyList?.forEach { item ->
            val oldValue = mValueMap[item.funNum]
            if (!valueChanged) {
                valueChanged = oldValue?.value != item.`val` || oldValue?.unit != item.unit
            }
            mValueMap[item.funNum] = BoardValue(item.`val`, item.unit, item.formatVal)
        }

        if (valueChanged) {
            notifyDataSetChanged()
        }
    }

    fun updateWaringValue(data: List<LabBulletinBoardVo>?) {
        val newlyList = data?.filter { !goneSensor(it.funNum) }

        var valueChanged = mWarningSet.size != newlyList?.size
        if (!valueChanged) {
            val changedItem = newlyList?.find { !mWarningSet.contains(it.funNum) }
            valueChanged = null != changedItem
        }

        mWarningSet.clear()
        newlyList?.forEach { item ->
            mWarningSet.add(item.funNum)
        }

        if (valueChanged) {
            notifyDataSetChanged()
        }
    }

    override fun convert(holder: BaseViewHolder, item: LabBulletinBoardVo) {
        val itemView = holder.itemView as ItemBoardView
        itemView.setSensorInfo(
            item.describe,
            mSensorMap[item.funNum]?.icon ?: R.mipmap.icon_sy_wzcgq
        )
        val itemVal = mValueMap[item.funNum]
        itemView.setSensorValue(itemVal?.value, itemVal?.unit, mWarningSet.contains(item.funNum))
    }

    private data class BoardValue(val value: String?, val unit: String?, val formatVal: String?)

}

// type 1-值班人员 2-准入人员
private class PersonFlipperAdapter(
    private val type: Int,
    private val data: List<LabPersonVo>?,
) :
    BaseAdapter() {

    override fun getCount() = data?.size ?: 0

    override fun getItem(position: Int): LabPersonVo? {
        return data?.get(position)
    }

    override fun getItemId(position: Int) = position.toLong()

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        val rootView: View
        val viewHolder: ViewHolder
        if (convertView == null) {
            val viewBinding =
                ItemHomePersonFlipperBinding.inflate(LayoutInflater.from(parent!!.context))
            rootView = viewBinding.root
            viewHolder = ViewHolder(viewBinding.pPhoto, viewBinding.pName, viewBinding.pCardNumber)
            rootView.tag = viewHolder
        } else {
            rootView = convertView
            viewHolder = convertView.tag as ViewHolder
        }

        getItem(position)?.let {
            Glide.with(rootView.context)
                .load(it.avatar)
                .placeholder(R.mipmap.icon_sign_in_avatar)
                .error(R.mipmap.icon_sign_in_avatar)
//                .transform(RoundedCorners(DeviceUtils.dip2px(context, 6f)))
                .into(viewHolder.imageView)

            viewHolder.name.text = it.userName

            if (1 == type) {
                viewHolder.number.text = it.userPhone // 值班人员
            } else {
                viewHolder.number.text = "准入期限：${formatValidTime(it.validEndTime)}" // 准入人员
            }
        }
        return rootView
    }

    private fun formatValidTime(input: String?): String {
        // 2023-10-10 => 23-10-10
        return if (input.isNullOrEmpty()) "" else input.substring(2, input.length)
    }

    class ViewHolder(
        val imageView: ImageView,
        val name: TextView,
        val number: TextView,
    )

}


// type 1-值班人员 2-准入人员
private class PersonFlipperAdapterTwo(
    private val type: Int,
    private val data: List<LaboratoryVo>?,
) :
    BaseAdapter() {

    override fun getCount() = data?.size ?: 0

    override fun getItem(position: Int): LaboratoryVo? {
        return data?.get(position)
    }

    override fun getItemId(position: Int) = position.toLong()

    override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
        val rootView: View
        val viewHolder: ViewHolder
        if (convertView == null) {
            val viewBinding =
                ItemHomePersonFlipperBinding.inflate(LayoutInflater.from(parent!!.context))
            rootView = viewBinding.root
            viewHolder = ViewHolder(viewBinding.pPhoto, viewBinding.pName, viewBinding.pCardNumber)
            rootView.tag = viewHolder
        } else {
            rootView = convertView
            viewHolder = convertView.tag as ViewHolder
        }

        getItem(position)?.let {
            Glide.with(rootView.context)
                .load(it.avatar)
                .placeholder(R.mipmap.icon_sign_in_avatar)
                .error(R.mipmap.icon_sign_in_avatar)
                .into(viewHolder.imageView)
//              RcLog.info("============111==${it.adminUserDesc}")
            RcLog.info("=============负责人 ${it.adminName}")
            viewHolder.name.text = it.adminName //负责人
            viewHolder.number.text = it.adminPhone // 电话
//            if (1 == type) {
//              //
//            } else {
//                viewHolder.number.text = "准入期限：${formatValidTime(it.validEndTime)}" // 准入人员
//            }
        }
        return rootView
    }

    private fun formatValidTime(input: String?): String {
        // 2023-10-10 => 23-10-10
        return if (input.isNullOrEmpty()) "" else input.substring(2, input.length)
    }

    class ViewHolder(
        val imageView: ImageView,
        val name: TextView,
        val number: TextView,
    )

}


// 实验人员Adapter
private class ExperimentPersonAdapter :
    BaseQuickAdapter<LabPersonVo, BaseViewHolder>(R.layout.item_home_person_flipper) {

    override fun convert(holder: BaseViewHolder, item: LabPersonVo) {
        Glide.with(context)
            .load(item.avatar)
            .placeholder(R.mipmap.icon_sign_in_avatar)
            .error(R.mipmap.icon_sign_in_avatar)
//            .transform(RoundedCorners(DeviceUtils.dip2px(context, 6f)))
            .into(holder.getView(R.id.pPhoto))

        // 签到时间：11-08 14:35
        holder.setText(R.id.pName, item.userName)
            .setText(R.id.pCardNumber, "签到时间：${formatSignTime(item.signTime)}")
            .setVisible(R.id.bottom_line, true)
    }

    private fun formatSignTime(time: String?): CharSequence {
        // 2023-03-30 15:45:25 => 03-30 15:45
        return if (time.isNullOrEmpty()) "" else time.subSequence(5, 16)
    }

}