package com.dlc.laboratory.ui.sign

import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.view.KeyEvent
import androidx.viewbinding.ViewBinding
import com.dlc.eboard.LabApp
import com.dlc.eboard.R
import com.dlc.eboard.common.CommonUtils
import com.dlc.eboard.common.Constants
import com.dlc.eboard.event.OnlineUserEvent
import com.dlc.eboard.iflytek.AudioPlayerManager
import com.dlc.eboard.serial.OnSerialScanListener
import com.dlc.eboard.serial.SerialPortHelper
import com.dlc.eboard.ui.auth.fragment.CardAuthFragment
import com.dlc.eboard.ui.dialog.CheckResultDialog
import com.dlc.eboard.ui.dialog.ResultEnum
import com.dlc.eboard.ui.dialog.SafetyCheckResultDialog
import com.dlc.eboard.ui.finger.EnrollAuthActivity
import com.dlc.eboard.ui.sign.SignInActivity
import com.dlc.eboard.ui.sign.SignInFragmentCallback
import com.rc.core.ui.fragment.RcBaseFragment
import com.rc.httpcore.client.ApiRepository
import org.greenrobot.eventbus.EventBus
import java.lang.ref.WeakReference

/**
 * info
 *
 * @author ReiChin_
 */
class ExSignInActivity:
    SignInActivity(),
    SignInFragmentCallback {
    private val weakHandler by lazy {  WeakReferenceHandler(this) }
    override fun initViews(savedInstanceState: Bundle?) {
        super.initViews(savedInstanceState)

        viewBinding.titleBar.setSigned(false)
        viewBinding.titleBar.setShowNotice(false)
        viewBinding.navView.setShowHome(false)
    }

    override fun showDefaultFragment() {
        val transaction = supportFragmentManager.beginTransaction()
        transaction.add(
            R.id.container,
            CardAuthFragment.newInstance(),
            CardAuthFragment.TAG
        )
        transaction.commitAllowingStateLoss()
    }

    override fun enabledLogoutCountDown() = false

    override fun switchFragment(fragment: RcBaseFragment<out ViewBinding>) {
        supportFragmentManager.beginTransaction().apply {
//            fragment.arguments = Bundle().apply {
//                putInt("sign_type", mSignType)
//            }
            replace(R.id.container, fragment, fragment.javaClass.simpleName)
            commitAllowingStateLoss()
        }
    }

    override fun initData() {
        if (Constants.Mock.SCHOOL_NUM_TEST) {
//            object : Handler(Looper.getMainLooper()) {
//
//                override fun handleMessage(msg: Message) {
//                    dispatchReadCardResult(Constants.Mock.SCHOOL_NUM)
//                }
//            }.sendEmptyMessageDelayed(1, 1500)
            weakHandler.sendEmptyMessageDelayed(1, 1500)
        }
    }

    override fun onResume() {
        mSerialPortHelper.onResume()
        super.onResume()
    }

    override fun onPause() {
        mSerialPortHelper.onPause()
        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) {
                if (Constants.Mock.JUMP_FACE_AUTH) {
                    callStudentCheckApi(content)
                } else {
                    dispatchReadCardResult(content)
                }
            }
        })
    }

    private fun cardAuthIsTopFragment(): Boolean {
        return supportFragmentManager.findFragmentByTag(CardAuthFragment.TAG)?.isResumed ?: false
    }

    private fun dispatchReadCardResult(username: String) {
        // 判断顶部Fragment是否是CardAuthFragment
        if (!cardAuthIsTopFragment()) return

        val fragment =
            supportFragmentManager.findFragmentByTag(SignInFaceMatchingFragment::class.java.simpleName)
                    as? SignInFaceMatchingFragment ?: SignInFaceMatchingFragment()
        fragment.arguments = Bundle().apply {
            putString("username", username)
        }
        switchFragment(fragment)
    }

    /**
     * step1) 获取签到人员
     */
    private fun callStudentCheckApi(username: String) {
        val labConfig = LabApp.sLabConfig
        if (null == labConfig) {
            showToast("暂无实验室信息，即将重新获取")
            CommonUtils.restartApp(this)
            return
        }

        showLoading("查询中...")
        val disposable = ApiRepository.signInCheck(false, labConfig.labId, username)
            .subscribe({ data ->
                if (data.state) {
                    callSignInApi(data.code)
                } else {
                    dismissLoading()
                    // 弹出核验结果的Dialog，5秒后关闭Dialog
                    CheckResultDialog().apply {
                        setSuccess(false)
                        isCancelable = false
                        setFinishOnTouchOutside(false)
                    }.show(supportFragmentManager, CheckResultDialog::class.java.simpleName)
                }
            }, { throwable ->
                dismissLoading()
                throwable.printStackTrace()
                showNetError(throwable)
            })
        addDisposable(disposable)
    }

    /**
     * step2) 人脸验证+最终签到
     */
    private fun callSignInApi(code: String) {
        val disposable = ApiRepository.jumpFaceSignIn(code)
            .subscribe({ success ->
                dismissLoading()
                if (success) {
                    EventBus.getDefault().post(OnlineUserEvent())
                    val message = "签到成功"
                    AudioPlayerManager.speakVoice(R.raw.audio_success_sign)
                    SafetyCheckResultDialog(
                        this,
                        ResultEnum.SUCCESS,
                        message,
                        3000
                    ).apply {
                        setCancelable(false)
                        setCanceledOnTouchOutside(false)
                        setOnDismissListener { finish() }
                        show()
                    }
                }
            }, { throwable ->
                dismissLoading()
                throwable.printStackTrace()
                showNetError(throwable)
            })
        addDisposable(disposable)
    }
    // static + 弱引用  防止内存泄露
    class WeakReferenceHandler(obj: ExSignInActivity) : Handler(Looper.getMainLooper()) {
        private val mRef: WeakReference<ExSignInActivity> = WeakReference(obj)

        override fun handleMessage(msg: Message) {
            mRef.get()?.run {
                dispatchReadCardResult(Constants.Mock.SCHOOL_NUM)
            }
        }
    }

    override fun onDestroy() {
        weakHandler.removeCallbacksAndMessages(null)
        super.onDestroy()
    }
}