package com.dlc.eboard.finger

import android.content.Context
import android.hardware.usb.UsbDevice
import android.util.Base64
import com.eyecool.fp.client.Callback
import com.eyecool.fp.client.TcFingerClient
import com.eyecool.fp.entity.FingerResult
import com.eyecool.fp.util.*
import com.rc.core.log.RcLog
import com.rc.httpcore.vo.response.UserFingerVo

/**
 * info
 *
 * @author ReiChin_
 */
class FingerManager(private val listener: OnFingerListener?) {

    private lateinit var mUsbUtil: USBUtil
    private var mClient: TcFingerClient? = null

    private var mFingers: List<UserFingerVo>? = null

    private var mLabFingerSuccess = false
    private var mDeviceConnected = false

    fun setFingers(fingers: List<UserFingerVo>) {
        this.mFingers = fingers
        this.mLabFingerSuccess = true
    }

    fun initDevice(appContext: Context) {
        RcLog.info("[finger init]init finger device")
        mUsbUtil = USBUtil.getInstance(appContext)
        // 设置设备使用协议
        mUsbUtil.setProtocol(USBUtil.Protocol.SIMPLE)
        // 设置特征类型
        FpConfig.setFeatureType(FpConfig.FEATURE_TYPE_BASE64)
        // 设置出图规格
        FpConfig.setImageType(FpConfig.IMAGE_BIG)
        // 设置质量分数
        FpConfig.setQualityScore(30)
        // 注册按3次判断指纹图像位置及质量（默认false）
        FpConfig.setCheckFingerQty(true)
        // 注册广播
        mUsbUtil.registerMonitor()
        // 关闭SDK中指纹日志输出
        Logs.setsIsLogEnabled(false)

        mUsbUtil.setConnectListener(object: OnUsbConnectListener() {
            override fun onConnected(client: TcFingerClient?) {
                RcLog.info("[finger enroll]指纹设备连接成功")
                // 获取指纹操作客户端
                mClient = client
                mDeviceConnected = true
                listener?.onConnected()
            }

            override fun onConnectFailed(code: Int, msg: String?) {
                RcLog.info("[finger enroll]指纹设备连接失败，code=${code},msg=${msg}")
                msg?.let { listener?.showToast(it) }
            }

            override fun onDisconnected() {
                RcLog.info("[finger enroll]指纹设备已断开连接")
                // mProgressDialog.dismiss()
            }

            override fun onAttach(usbDevice: UsbDevice?) {
                RcLog.info("[finger enroll]指纹设备onAttach, pid=${usbDevice?.productId},vid:${usbDevice?.vendorId}")
            }

            override fun onDettach(usbDevice: UsbDevice?) {
                RcLog.info("[finger enroll]指纹设备onDettach, pid=${usbDevice?.productId},vid:${usbDevice?.vendorId}")
            }
        })
        // 打开设备
        mUsbUtil.connectDevice()
    }

    fun enroll(callback: Callback, timeout: Int = 30000) {
        if (!isDeviceReady()) return

        mClient?.tcEnroll(callback, timeout)
    }

    fun lazyVerify() {
        if (mLabFingerSuccess && mDeviceConnected) verify()
    }

    fun verify(timeout: Int = 5000) {
        if (!isDeviceReady()) return

        mClient?.tcGetFeature(timeout, object: Callback() {

            override fun onSuccess(result: FingerResult?) {
                var matchFingerVo: UserFingerVo? = null
                mFingers?.forEach { fingerVo ->
                    val template = Base64.decode(fingerVo.finger, Base64.NO_WRAP)
                    val matchResult = mClient?.tcMatch(result?.template, template)
                    if (matchResult?.status ?: 0 >= 0) {
                        RcLog.info("[finger match]指纹比对成功, score=${matchResult?.score}, userId=${fingerVo.userId}, userName=${fingerVo.userName}, userType=${fingerVo.userType}")
                        matchFingerVo = fingerVo
                        return@forEach
                    }
                }
                if (null != matchFingerVo) {
                    listener?.onMatchSuccess(matchFingerVo!!)
                } else {
                    listener?.onMatchFailure("验证失败")
                }
            }

            override fun onError(errorCode: Int) {
                RcLog.info("[finger match]指纹比对失败,errorCode=${errorCode},errorInfo=${FingerErrorCode.decode(errorCode)}")
                if (FpConst.TCY_TMOT != errorCode // 操作超时
                    && FpConst.TCY_CNCL != errorCode // 取消操作
                    && FpConst.TCY_NLNK != errorCode // 设备断开
                ) {
                    listener?.onMatchFailure("验证失败，${FingerErrorCode.decode(errorCode)}")
                } else {
                    verify()
                }
            }
        })
    }

    private fun isDeviceReady(): Boolean {
        if (mClient == null) {
            RcLog.info("[finger ready]指纹设备未连接")
            listener?.showToast("设备未连接")
            return false
        }
        if (mClient!!.isBusy) {
            RcLog.info("[finger ready]指纹设备忙")
            listener?.showToast("设备忙")
            return false
        }
        return true
    }

    fun releaseDevice() {
        RcLog.info("[finger release]disconnect finger device")
        mUsbUtil.unRegisterMonitor()
        mUsbUtil.asynDisconnectDevice()
    }

}