package com.example.chemical.ui.login


import android.content.IntentFilter
import android.hardware.usb.UsbManager
import android.os.*
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.example.chemical.ChemicalApp
import com.example.chemical.R
import com.example.chemical.comm.Constants
import com.example.chemical.databinding.ActivityFacialCardBinding
import com.example.chemical.receiver.OnSerialScanListener
import com.example.chemical.receiver.PortScanHelper
import com.example.chemical.receiver.UsbReceiver
import com.example.chemical.ui.common.BaseCountDownActivity
import com.example.chemical.utils.MediaPlayerHelper
import com.example.chemical.weidith.AuthenticationDialog
import com.example.chemical.weidith.CustomDialog
import com.rc.core.log.RcLog
import com.rc.httpcore.HttpClient
import com.rc.httpcore.HttpConfig
import com.rc.httpcore.client.ApiRepository
import com.rc.httpcore.exception.NetException
import com.rc.httpcore.vo.request.FaceCompareReq
import io.fotoapparat.Fotoapparat
import io.fotoapparat.facedetector.processor.FaceDetectorProcessor
import io.fotoapparat.log.fileLogger
import io.fotoapparat.log.logcat
import io.fotoapparat.log.loggers
import io.fotoapparat.selector.back
import io.fotoapparat.selector.front
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import retrofit2.HttpException
import java.io.File
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.text.SimpleDateFormat
import java.util.*

//刷卡+人脸   登录方式
class FacialCardActivity : BaseCountDownActivity<ActivityFacialCardBinding>() {
    private var mUsbReceiver: UsbReceiver? = null  // 刷卡广播注册
    private var mHandleScanEvent = false //当前是否已经获取过 usb返回的参数
    private lateinit var mFotoapparat: Fotoapparat

    //    private lateinit var mCountDownTimer: CountDownTimer
    private var alertDialog: AlertDialog? = null
    private var faceList: String? = null
    private var mFaceImg: String? = null
    private var mUserName: String = ""
    private val handlerBack = Handler(Looper.getMainLooper())
    private val totalTimeInMillis: Long = 40 * 1000 // 总时常
    private var timeLeftInSeconds = 2
    private var mTvView: TextView? = null
    private var mDialogsAut: AuthenticationDialog? = null
    private val countHandler = Handler(Looper.getMainLooper()) //整个页面 60秒后 直接关闭

    override fun createViewBinding() = ActivityFacialCardBinding.inflate(LayoutInflater.from(this))

    override fun initViews(savedInstanceState: Bundle?) {
        super.initViews(savedInstanceState)
        //注册广播
        EventBus.getDefault().register(this)
        MediaPlayerHelper.playRawMp3(this, R.raw.login_shua_ka)
        viewBinding.tvReturn.text = "返回${ChemicalApp.confs!!.backTime}s"
        viewBinding.tvReturn.setOnClickListener {
            finish()
        }
        //重新人脸识别
        viewBinding.butAgain.setOnClickListener {
            handlerBack.post(countdownRunnableTwo)
        }
        // 使用 Glide 加载网络图片
        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)
        countHandler.postDelayed({
            finish()
        }, totalTimeInMillis) // 50秒后关闭
    }

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

    //===========================人脸识别=========================


    private val countdownRunnableTwo = object : Runnable {
        override fun run() {
//            if (timeLeftInSeconds > 0) {
//                mTvView!!.text = "${timeLeftInSeconds}秒后自动返回首页"
//                timeLeftInSeconds--
//                handlerBack.postDelayed(this, 1000)
//            } else {
//                mDialogsAut!!.dismiss()
//                finish()
//            }
            RcLog.info("=======刷卡人脸认证中")
            takePicture()
            handlerBack.postDelayed(this, 4000)
        }
    }


    private fun takePicture() {
        val format = SimpleDateFormat("yyyyMMdd_HHmmssSSS", Locale.getDefault())
        val fileName = "${format.format(Calendar.getInstance().time)}.jpg"
        val photoFile = File(this.getExternalFilesDir("photos"), fileName)
        mFotoapparat.takePicture()
            .saveToFile(photoFile)
            .whenAvailable {
                callFaceMatchingApi(photoFile)
            }
    }

    private fun callFaceMatchingApi(
        featureData: File,
    ) {
        showLoading("比对中....")
        val param = FaceCompareReq().apply {
            data = null
            userIds = faceList
        }
        val disposable = ApiRepository.faceCompare(featureData, param)
            .subscribe({ success ->
                dismissLoading()
                if (faceList.equals(success.userId)) {
                    ChemicalApp.userData = success
                    authenticationDialog()
                } else {
                    customDialogView(2, "不是同一个人")
                }
            }, { throwable ->
                dismissLoading()
                throwableView(throwable)
                HttpClient.token = null
                ChemicalApp.userData = null
            })
        addDisposable(disposable)
    }


    //后置
    private fun getFaceBack() {
        viewBinding.radio.visibility = View.GONE
        viewBinding.rlResult.visibility = View.VISIBLE
        viewBinding.imgFace.visibility = View.GONE
//        viewBinding.through.visibility = View.VISIBLE
//        viewBinding.userName.text = "$mUserName"
//        Glide.with(this)
//            .load("${HttpConfig.API_BASE_IMG_URL}$mFaceImg")
//            .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.AUTOMATIC))
//            .error(R.mipmap.icon_zhan_wei)
//            .into(viewBinding.imgView)
        MediaPlayerHelper.playRawMp3(this, R.raw.login_ren_lian)
        HttpClient.token = null
        mFotoapparat = Fotoapparat.with(this)
            .into(viewBinding.cameraView)
            .lensPosition(
                if (Constants.FACE_TAG == 0) {
                    front()
                } else {
                    back()
                }
            )//front（）前置  back 后置
            .frameProcessor(
                FaceDetectorProcessor.with(this)
                    .listener { faces ->
                        viewBinding.rectanglesView.setRectangles(faces)
                    }.build()
            )
            .logger(loggers(logcat(), fileLogger(this)))
            .build()
        mFotoapparat.stop()
        mFotoapparat.start()
        handlerBack.post(countdownRunnableTwo)
    }

    //===========================end============================


    private val mPortScanHelper by lazy {
        PortScanHelper(this, object : OnSerialScanListener {
            override fun dispatchScanEvent(type: OnSerialScanListener.ScanType, content: String) {
                if (!mHandleScanEvent) {
                    if (content.isNotBlank()) {
                        RcLog.info("==========当前usb返回参数$content")
                        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) {
        HttpClient.token = null
        showLoading("登录中...")
        val disposable = ApiRepository.cardNum(cont)
            .subscribe({ data ->
                ChemicalApp.userData = data
//                ChemicalApp!!.userData!!.cardNum = cont
                faceList = data.userId
                mUserName = data.userName
                authenticationInfo(data.userId, ChemicalApp.subjectId!!)
            }, { throwable ->
                dismissLoading()
                throwableView(throwable)
                mHandleScanEvent = false
            })
        addDisposable(disposable)
    }


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

            }, { throwable ->
                dismissLoading()
//                showNetError(throwable)
                throwableView(throwable)
                HttpClient.token = null
                ChemicalApp.userData = null
                mHandleScanEvent = false
            })
        addDisposable(disposable)
    }

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


    override fun onBackPressed() {
        super.onBackPressed()
        finish()
    }

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

    //获取刷卡信息
    override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
        mPortScanHelper.dispatchKeyEvent(event)
        return super.dispatchKeyEvent(event)
    }

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

        try {
            mFotoapparat.stop()
//            mCountDownTimer.cancel()
        } catch (e: Exception) {
        }
        super.onPause()
    }

    override fun onStop() {
        super.onStop()
        try {
            mFotoapparat.stop()
        } catch (e: Exception) {
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        mPortScanHelper.onPause()
        // 停止定时更新
        unregisterReceiver(mUsbReceiver)
        EventBus.getDefault().unregister(this) //关闭广播
        try {
            mFotoapparat.stop()
            handlerBack.removeCallbacks(countdownRunnableTwo)
        } catch (e: Exception) {
        }
        try {
            handlerBack.removeCallbacks(countdownRunnable)
            handlerBack.removeCallbacksAndMessages(null)
        } catch (e: Exception) {

        }

        try {
            countHandler.removeCallbacksAndMessages(null)
        } catch (e: Exception) {
        }
    }

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

    }


    //身份认证成功
    private fun authenticationDialog() {
        handlerBack.removeCallbacks(countdownRunnableTwo)
        MediaPlayerHelper.playRawMp3(this, R.raw.login_ren_zheng_tong_hua)
        mDialogsAut = AuthenticationDialog(
            this,
            mFaceImg,
            ChemicalApp.confs!!.subName,
            ChemicalApp.confs!!.deptName,
            "${ChemicalApp.confs!!.buildName}${ChemicalApp.confs!!.floorName}",
            mUserName,
            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) {
        val customDialog = CustomDialog(this, types, msg)
        if (!this.isFinishing && !this.isDestroyed) {
            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") }
    }
}