package com.example.chemical.ui.login


import android.os.*
import android.util.Log
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.widget.TextView
import com.blankj.utilcode.util.AppUtils
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.example.chemical.ChemicalApp
import com.example.chemical.R
import com.example.chemical.comm.Constants
import com.example.chemical.databinding.ActivityFacialLoginBinding
import com.example.chemical.ui.common.BaseCountDownActivity
import com.example.chemical.utils.HandlerUtil
import com.example.chemical.utils.MediaPlayerHelper
import com.example.chemical.utils.UiManager
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 retrofit2.HttpException
import java.io.File
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.text.SimpleDateFormat
import java.util.*

/**
 * 人脸登录
 */
class FacialLoginActivity : BaseCountDownActivity<ActivityFacialLoginBinding>() {

    private lateinit var mFotoapparat: Fotoapparat
//    private lateinit var mCountDownTimer: CountDownTimer

    //人脸验证时间
    private val totalTimeInMillis: Long = 30 * 1000 // 总时常
    private lateinit var faceList: String
    private val handlerBack = Handler(Looper.getMainLooper())
    private var timeLeftInSeconds = 2
    private var mTvView: TextView? = null
    private var mDialogsAut: AuthenticationDialog? = null
    private val countHandler = Handler(Looper.getMainLooper()) //整个页面 60秒后 直接关闭

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

    override fun initViews(savedInstanceState: Bundle?) {
        super.initViews(savedInstanceState)
        MediaPlayerHelper.playRawMp3(this, R.raw.login_ren_lian)
        // 使用 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)
        var str = ""

        try {
            str = intent.getStringExtra("faceList")!!
        } catch (e: Exception) {
        }
        val mtypes = intent.getStringExtra("mtypes")
        try {
            when (mtypes) {
                "1" -> {
                    viewBinding.linType.visibility = View.GONE
                }

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

                "5" -> {
                    viewBinding.tvSwipe.visibility = View.GONE
                }

            }
        } catch (e: Exception) {

        }

        val map = mutableMapOf<String, String>()
        if (mtypes != null) {
            map["mtypes"] = mtypes
        }
        if (str != null && str.length > 0) {
            // 去除字符串首尾的中括号
            faceList = str.removeSurrounding("[", "]")
            map["faceList"] = str
        }

        //跳转刷卡登录
        viewBinding.tvSwipe.setOnClickListener {
            UiManager.switcher(this, map, SwipeActivity::class.java)
            finish()
        }
        // TODO 测试通道
        if (AppUtils.isAppDebug()) {
            viewBinding.tvSwipe.performClick()
        }
        //跳转扫码登录
        viewBinding.tvScan.setOnClickListener {
            UiManager.switcher(this, map, ScanLoginActivity::class.java)
            finish()
        }

        viewBinding.tvReturn.text = "返回${ChemicalApp.confs!!.backTime}s"
        viewBinding.tvReturn.setOnClickListener {
            finish()
        }

        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()
//        mCountDownTimer = object : CountDownTimer(totalTimeInMillis, 1000) {
//            override fun onTick(millisUntilFinished: Long) {
//                val secondsRemaining = millisUntilFinished / 1000
//                // 在最后六秒进行提示
//                if (secondsRemaining.toInt() == 6) {
//                    val message = "多次识别失败 $secondsRemaining 秒后关闭当前页面，请注意！"
//                    showToast(message)
//                }
//            }
//
//            override fun onFinish() {
//                mFotoapparat.stop()
//                cancelTime()
//                finish()
//            }
//        }
//        mCountDownTimer.start()
        handlerBack.post(countdownRunnableTwo)
        countHandler.postDelayed({
            finish()
        }, totalTimeInMillis) // 15秒后关闭对话框
    }

    override fun onStart() {
        super.onStart()
//        mFotoapparat.start()
    }

    override fun onStop() {
        super.onStop()
//        mFotoapparat.stop()
    }

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

    override fun onDestroy() {
        super.onDestroy()
//        cancelTime()//手动关闭
        RcLog.info("=============onDestroy")

//        handlerUtil.removeCallbacks(task)
//        handlerUtil.stopAllTasks()
        // 移除回调，以防止内存泄漏
        try {
            mFotoapparat.stop()
            handlerBack.removeCallbacks(countdownRunnable)
            handlerBack.removeCallbacks(countdownRunnableTwo)
            handlerBack.removeCallbacksAndMessages(null)
            dismissLoading()
        } catch (e: Exception) {

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

    private fun takePicture() {
        RcLog.info("=======111人脸登录任务进行中")
        val format = SimpleDateFormat("yyyyMMdd_HHmmssSSS", Locale.getDefault())
        val fileName = "${format.format(Calendar.getInstance().time)}.jpg"
        val photoFile = File(this.getExternalFilesDir("photos"), fileName)
        try {
            mFotoapparat.takePicture()
                .saveToFile(photoFile)
                .whenAvailable {
                    callFaceMatchingApi(photoFile)
                }
        } catch (e: Exception) {
        }
    }

    private fun callFaceMatchingApi(
        featureData: File,
    ) {
        showLoading("比对中....")
        val param = FaceCompareReq().apply {
            data = null
            userIds = faceList
        }
        val disposable = ApiRepository.faceCompare(featureData, param)
            .subscribe({ success ->
                dismissLoading()
                LogUtils.json(success)
                ChemicalApp.userData = success
                LogUtils.d(success.userId, ChemicalApp.subjectId)
                authenticationInfo(success.userId, ChemicalApp.subjectId!!)
            }, { throwable ->
                dismissLoading()
                throwableView(throwable)
            })
        addDisposable(disposable)
    }

    //验证当前人员身份
    private fun authenticationInfo(userId: String, subId: String) {
        LogUtils.d(userId, subId)
        showLoading("验证中...")
        val disposable = ApiRepository.userCardValidation(userId, subId)
            .subscribe({ data ->
                LogUtils.json(data)
                dismissLoading()
                val allFalse = with(data) {
                    cabinetAdmin == false &&
                            belongUser == false &&
                            toipcUser == false &&
                            safeUser == false &&
                            collegeAdmin == false &&
                            schoolLevelAdmin == false &&
                            adminUser == false
                }
                ChemicalApp.responsibles = false
                ChemicalApp.administrators = 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 校级管理员
                        ChemicalApp.administrators = true
                        authenticationDialog(data.faceImg, data.userName)
                    } else if (data.adminUser == true || data.safeUser == true || data.cabinetAdmin == true) {
                        //实验室负责人 or  安全负责人 or 柜锁管理员
                        ChemicalApp.responsibles = true
                        authenticationDialog(data.faceImg, data.userName)
                    } else if (data.belongUser == true || data.toipcUser == true) {  //当前身份 归属人or课题组
                        ChemicalApp.responsibles = false
                        ChemicalApp.administrators = false
                        authenticationDialog(data.faceImg, data.userName)
                    } else {
                        HttpClient.token = null
                        ChemicalApp.userData = null
                        customDialogView(2, "身份认证不通过")
                    }

                }

            }, { throwable ->
                dismissLoading()
                //暂时注释掉  防止异步请求后 在认证时 token 丢失
//                startCountdownAndExecuteMethod()
                throwableView(throwable)
            })
        addDisposable(disposable)
    }

    //身份认证成功
    private fun authenticationDialog(faceImg: String?, userName: String) {
        mFotoapparat.stop()
        handlerBack.removeCallbacks(countdownRunnableTwo)
        MediaPlayerHelper.playRawMp3(this, R.raw.login_ren_zheng_tong_hua)
        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()
            }
        }
    }

    private val countdownRunnableTwo = object : Runnable {
        override fun run() {
            takePicture()
            handlerBack.postDelayed(this, 4000)
        }
    }

    /**
     * 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) {
        LogUtils.e(Log.getStackTraceString(throwable))
        when (throwable) {
            is NetException -> {
                if (throwable.message.isNullOrEmpty()) {
                    "接口请求失败(${throwable.code})"
                } else {
                    throwable.message!!
                }
            }

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

}