package xn.hxp.ui.login

import android.content.IntentFilter
import android.hardware.usb.UsbManager
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.widget.TextView
import androidx.viewbinding.ViewBinding
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.LogUtils
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.rc.core.ui.activity.BaseActivity
import com.rc.httpcore.HttpClient
import com.rc.httpcore.HttpConfig
import com.rc.httpcore.bean.UserData
import com.rc.httpcore.client.ApiRepository
import com.rc.httpcore.exception.NetException
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import retrofit2.HttpException
import xn.hxp.R
import xn.hxp.app.ChemicalApp
import xn.hxp.databinding.ActivitySwipeBinding
import xn.hxp.receiver.OnSerialScanListener
import xn.hxp.receiver.PortScanHelper
import xn.hxp.receiver.UhfRfidManager
import xn.hxp.receiver.UsbReceiver
import xn.hxp.ui.MainActivity
import xn.hxp.utils.AudioPlayer
import xn.hxp.utils.UiManager
import xn.hxp.weidith.AuthenticationDialog
import xn.hxp.weidith.CustomDialog
import java.net.ConnectException
import java.net.SocketTimeoutException

/**
 * 刷卡登录
 */
class SwipeActivity : BaseActivity() {
    private var mUsbReceiver: UsbReceiver? = null  // 刷卡广播注册
    private var mHandleScanEvent = false //当前是否已经获取过 usb返回的参数

    lateinit var viewBinding: ActivitySwipeBinding
    override fun setViewBinding(): ViewBinding {
        viewBinding = ActivitySwipeBinding.inflate(layoutInflater)
        return viewBinding
    }

    override fun onInit() {
        AudioPlayer.getInstance().play(R.raw.scan_card)
        //注册广播
        EventBus.getDefault().register(this)
        viewBinding.tvReturn.text = "返回${ChemicalApp.confs!!.backTime}s"
        viewBinding.tvReturn.setOnClickListener {
            ActivityUtils.finishToActivity(MainActivity::class.java, false)
        }

        val stringExtra = intent.getStringExtra("mtypes")
        when (stringExtra) {
            "1" -> {
                viewBinding.linType.visibility = View.GONE
            }

            "6" -> {
                viewBinding.tvFace.visibility = View.GONE
            }

            "4" -> {
                viewBinding.tvWx.visibility = View.GONE
            }
        }

        viewBinding.deptName.text = "${ChemicalApp.confs!!.deptName}-${ChemicalApp.confs!!.roomNum}"
        Glide.with(this)
            .load("${HttpConfig.API_BASE_IMG_URL}${ChemicalApp.confs!!.circularLogo}")
            .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.AUTOMATIC))
            .into(viewBinding.image)
        val map = mutableMapOf<String, String>()
        if (stringExtra != null) {
            map["mtypes"] = stringExtra
        }
        try {
            val face = intent.getStringExtra("faceList")
            if (face != null) {
                map["faceList"] = face
            }
        } catch (e: Exception) {

        }
        viewBinding.tvFace.setOnClickListener {
            UiManager.switcher(this, map, FaceLoginActivity::class.java)
            finish()
        }

        viewBinding.tvWx.setOnClickListener {
            if (stringExtra != null) {
                map["mtypes"] = stringExtra
            }
            UiManager.switcher(this, map, ScanLoginActivity::class.java)
            finish()
        }
    }

    override fun onResume() {
        super.onResume()
        mPortScanHelper.onResume()
        registerUsbBroadcast()
    }


    private val mPortScanHelper by lazy {
        PortScanHelper(this, object : OnSerialScanListener {
            override fun dispatchScanEvent(type: OnSerialScanListener.ScanType, content: String) {
                if (!mHandleScanEvent) {
                    if (content.isNotBlank()) {
                        mHandleScanEvent = true
                        handleScanEvent(content)
                    }

                }
            }

        })
    }

    //刷卡usb链接
    private fun registerUsbBroadcast() {
        if (null == mUsbReceiver) {
            val filter = IntentFilter().apply {
                addAction(UsbReceiver.ACTION_USB_PERMISSION)
                addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED)
                addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
                addAction(UsbReceiver.ACTION_USB_STATE) // usb连接状态广播
            }
            mUsbReceiver = UsbReceiver()
            registerReceiver(mUsbReceiver, filter)
        }
    }

    //调用刷卡信息
    private fun handleScanEvent(cont: String) {
        showLoading("登录中...")
        HttpClient.token = null
        val disposable = ApiRepository.cardNum(cont)
            .subscribe({ data ->
                ChemicalApp.userData = data
                authenticationInfo(data, ChemicalApp.subjectId!!)
            }, { throwable ->
                dismissLoading()
                throwableView(throwable)
                mHandleScanEvent = false
            })
        addDisposable(disposable)
    }

    //验证当前人员身份
    private fun authenticationInfo(user: UserData, subId: String) {
        showLoading("验证中...")
        val disposable = ApiRepository.userCardValidation(user.userId, subId)
            .subscribe({ data ->
                ChemicalApp.userData!!.userValidationBean = data
                dismissLoading()
                LogUtils.json("登录人", data)
                val allFalse =
                    java.lang.Boolean.TRUE == data.cabinetAdmin || java.lang.Boolean.TRUE == data.belongUser || java.lang.Boolean.TRUE == data.toipcUser || java.lang.Boolean.TRUE == data.safeUser || java.lang.Boolean.TRUE == data.collegeAdmin || java.lang.Boolean.TRUE == data.schoolLevelAdmin || java.lang.Boolean.TRUE == data.adminUser || java.lang.Boolean.TRUE == data.apply || java.lang.Boolean.TRUE == data.white
                if (!allFalse) {
                    LogUtils.d("当前身份不符合")
                    HttpClient.token = null
                    ChemicalApp.userData = null
                    customDialogView(2, "当前身份不符合")
                    mHandleScanEvent = false
                } else {
                    //校级管理员 schoolLevelAdmin
                    //院级管理员  collegeAdmin
                    //实验室负责人 adminUser
                    //安全负责人 safeUser
                    //柜锁管理员 cabinetAdmin
                    //是否化学品归属人 belongUser
                    //是否化学品归属课题组下成员  toipcUser
                    if (data.schoolLevelAdmin == true || data.collegeAdmin == true) {
                        authenticationDialog(data.faceImg, data.userName)
                    } else if (data.adminUser == true || data.safeUser == true || data.cabinetAdmin == true) {
                        //实验室负责人 or  安全负责人 or 柜锁管理员
                        authenticationDialog(data.faceImg, data.userName)
                    } else if (data.belongUser == true || data.toipcUser == true) {  //当前身份 归属人or课题组
                        authenticationDialog(data.faceImg, data.userName)
                    } else if (data.white == true || data.apply == true) {// 白名单和实验室准入
                        authenticationDialog(data.faceImg, data.userName)
                    } else {
                        LogUtils.d("当前身份不符合")
                        HttpClient.token = null
                        ChemicalApp.userData = null
                        customDialogView(2, "当前身份不符合")
                        mHandleScanEvent = false
                    }

                }

            }, { throwable ->
                LogUtils.d("登录异常", throwable.message)
                dismissLoading()
                throwableView(throwable)
                HttpClient.token = null
                ChemicalApp.userData = null
                mHandleScanEvent = false
            })
        addDisposable(disposable)
    }

    //获取刷卡信息
    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
        // 消费掉外置RFID读卡器的输入
        if (UhfRfidManager.isEnabled(this) && UhfRfidManager.isUhfRfidEvent(this, event)) {
            return true
        }
        mPortScanHelper.dispatchKeyEvent(event)
        return super.dispatchKeyEvent(event)
    }

    //停止 销毁广播传递
    override fun onPause() {
        mPortScanHelper.onPause()
        super.onPause()
    }

    override fun onDestroy() {
        super.onDestroy()
        mPortScanHelper.onPause()
        // 移除回调，以防止内存泄漏
        try {
            handlerBack.removeCallbacks(countdownRunnable)
        } catch (e: Exception) {

        }
        unregisterReceiver(mUsbReceiver)
        // 停止定时更新
        EventBus.getDefault().unregister(this) //关闭广播
    }

    override fun cdFinish() {
        finish()
    }

    //必须写这个方法  防止注册失败
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onUpdateEventEvent(event: KeyEvent) {

    }


    override fun onBackPressed() {
        super.onBackPressed()
        ActivityUtils.finishToActivity(MainActivity::class.java, false)
    }

    override fun cdTime(cd: Int) {
        viewBinding.tvReturn.text = "返回${cd}s"
    }

    private val handlerBack = Handler(Looper.getMainLooper())
    private var timeLeftInSeconds = 2
    private var mTvView: TextView? = null
    private var mDialogsAut: AuthenticationDialog? = null

    //身份认证成功
    private fun authenticationDialog(faceImg: String?, userName: String) {
        AudioPlayer.getInstance().play(R.raw.verify_success)
        mDialogsAut = AuthenticationDialog(
            this,
            faceImg,
            ChemicalApp.confs!!.subName,
            ChemicalApp.confs!!.deptName,
            "${ChemicalApp.confs!!.buildName}${ChemicalApp.confs!!.floorName}",
            userName, object : AuthenticationDialog.IClickLit {
                override fun onUpView(tvView: TextView) {
                    mTvView = tvView
                }
            })
        mDialogsAut!!.show()
        // 开始倒计时
        handlerBack.post(countdownRunnable)
        // 获取对话框的 Window 对象
        mDialogsAut!!.window?.decorView?.setOnTouchListener { _, event ->
            // 判断是否点击了对话框外部空白区域
            if (event.action == MotionEvent.ACTION_DOWN) {
                val x = event.x
                val y = event.y
                val dialogView = mDialogsAut!!.window?.decorView
                if (dialogView != null && (x < 0 || x > dialogView.width || y < 0 || y > dialogView.height)) {
                    // 在此处执行点击对话框外部空白区域时的操作
                    // 例如关闭对话框
                    // 移除回调，以防止内存泄漏
                    mDialogsAut!!.dismiss()
                    finish()
                    return@setOnTouchListener true
                }
            }
            return@setOnTouchListener false
        }

    }

    private val countdownRunnable = object : Runnable {
        override fun run() {
            if (timeLeftInSeconds > 0) {
                mTvView!!.text = "${timeLeftInSeconds}秒后自动返回首页"
                timeLeftInSeconds--
                handlerBack.postDelayed(this, 1000)
            } else {
                mDialogsAut!!.dismiss()
                finish()
            }
        }
    }

    /**
     * 0  没有图标 1 绿色   2红色
     *   失败或者成功的弹框
     */
    private fun customDialogView(types: Int, msg: String) {
        if (!this.isFinishing && !this.isDestroyed) {
            val customDialog = CustomDialog(this, types, msg)
            customDialog.show()
        }
    }

    /**
     * 异常处理
     */
    private fun throwableView(throwable: Throwable) {
        when (throwable) {
            is NetException -> {
                if (throwable.message.isNullOrEmpty()) {
                    "接口请求失败(${throwable.code})"
                } else {
                    throwable.message!!
                }
            }

            is SocketTimeoutException -> "请求超时，请稍后重试"
            is ConnectException -> "无法连接服务器，请检查网络"
            is HttpException -> "服务器繁忙，请稍后重试"
            else -> null
        }?.let { customDialogView(2, "$it") }
    }

}