package com.dlc.exam.ui.common

import android.app.Activity
import android.content.Context
import android.content.DialogInterface
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import android.view.ViewTreeObserver
import androidx.appcompat.app.AlertDialog
import com.arcsoft.face.FaceFeature
import com.arcsoft.face.FaceInfo
import com.dlc.exam.ExamApp
import com.dlc.exam.camera.FaceEngineHelper
import com.dlc.exam.common.CommonUtils
import com.dlc.exam.databinding.FragmentFaceMatchingBinding
import com.dlc.exam.ui.exam.ExamFragmentCallback
import com.rc.core.log.RcLog
import com.rc.core.ui.fragment.RcBaseFragment
import com.rc.httpcore.HttpClient
import com.rc.httpcore.client.ApiRepository
import com.rc.httpcore.exception.NetException
import com.rc.httpcore.vo.request.FaceCompareReq
import java.io.File
import java.lang.ref.WeakReference
import kotlin.properties.Delegates

/**
 * 人脸验证
 *
 * @author ReiChin_
 */
class FaceMatchingFragment : RcBaseFragment<FragmentFaceMatchingBinding>(),
    ViewTreeObserver.OnGlobalLayoutListener, FaceEngineHelper.EngineCallback {

    private var faceEngineHelper: FaceEngineHelper? = null
    private var isLogin: String = "0"

    companion object {
        const val FRAGMENT_TAG = "FaceMatchingFragment"
        const val TYPE_LOGIN = 1
        const val TYPE_PRE_EXAM = 2 // 考前人脸验证
        const val TYPE_END_EXAM = 3 // 考后人脸验证

        fun newInstance(type: Int, username: String? = null): FaceMatchingFragment {
            val args = Bundle()
            args.putInt("type", type)
            args.putString("username", username)
            val fragment = FaceMatchingFragment()
            fragment.arguments = args
            return fragment
        }
    }

    private var mType by Delegates.notNull<Int>()

    override fun createViewBinding(
        inflater: LayoutInflater,
        container: ViewGroup?
    ) = FragmentFaceMatchingBinding.inflate(inflater, container, false)

    override fun initViews(savedInstanceState: Bundle?) {
        mType = requireArguments().getInt("type", TYPE_LOGIN)
//        isLogin= requireArguments().getString("islogin")!!
        // 在布局结束后才做初始化操作
        viewBinding.texturePreview.viewTreeObserver.addOnGlobalLayoutListener(this)

        viewBinding.cameraTips.text = "请将脸部对准摄像头"
    }

    /*
    * 在viewBinding.texturePreview第一次布局完成后，去除该监听，并且进行引擎和相机的初始化
    */
    override fun onGlobalLayout() {
        viewBinding.texturePreview.viewTreeObserver.removeOnGlobalLayoutListener(this)
        if (null == faceEngineHelper) {
            faceEngineHelper = FaceEngineHelper(
                WeakReference(requireActivity()),
                viewBinding.texturePreview,
                null, this
            ).apply {
                initEngineAndCamera()

                viewBinding.texturePreview.postDelayed({
                    startPreview()
                }, 100)
            }
        }
    }

    private fun startPreview() {
        // 核验通过，直接人脸识别
        faceEngineHelper?.isVisibleToUser = true
        faceEngineHelper?.stopPreview(false)
    }

    override fun onResume() {
        super.onResume()
        faceEngineHelper?.isVisibleToUser = true
    }

    override fun onPause() {
        faceEngineHelper?.isVisibleToUser = false
        super.onPause()
    }

    override fun onStop() {
        super.onStop()
        faceEngineHelper?.releaseEngineAndCamera()
    }

    override fun onDestroy() {
        super.onDestroy()
        faceEngineHelper?.releaseEngineAndCamera()
    }

    override fun onLivenessSuccess(
        nv21: ByteArray,
        width: Int,
        height: Int,
        faceInfo: FaceInfo?,
        callback: (comparing: Boolean) -> Unit
    ) {
        RcLog.info("活体检查成功，调用本地的比对方法")
    }

    override fun onFaceFile(file: File, callback: (comparing: Boolean) -> Unit) {
        RcLog.info("活体检查成功，已生成图片，调用后台服务人脸比对")
    }

    override fun onFaceFeature(faceFeature: FaceFeature, callback: (comparing: Boolean) -> Unit) {
        RcLog.info("人脸特征已生成，调用后台服务人脸比对，同时调用签到API")
        faceEngineHelper?.stopPreview(true)
        callback.invoke(true)

        // 调用人脸比对方法
        callFaceMatchingApi(faceFeature.featureData, callback)
    }

    private fun callFaceMatchingApi(
        featureData: ByteArray,
        callback: (comparing: Boolean) -> Unit
    ) {
        showLoading("比对中....")
        val param = FaceCompareReq().apply {
            data = featureData
            userId = ExamApp.sLearnLoginVo!!.user_id
        }
        val disposable = ApiRepository.faceCompare(param)
            .subscribe({ success ->
                dismissLoading()
                callback.invoke(false)
                if (success) {
                    dispatchMatchingSuccess()
                }
            }, { throwable ->
                callback.invoke(false)
                dismissLoading()
                if (!pretreatmentError(throwable)) {
                    faceEngineHelper?.stopPreview(false)
                    throwable.printStackTrace()
                    showNetError(throwable)
                }
            })
        addDisposable(disposable)
    }

    private fun dispatchMatchingSuccess() {
        when (mType) {
            TYPE_LOGIN -> {
                // 人脸比对成功，登录成功，进入主页
                callLearnLoginApi(true) {
                    requireActivity().apply {
                        setResult(Activity.RESULT_OK)
                        finish()
                    }
                }
            }
            TYPE_PRE_EXAM -> {
                // 考前人脸验证成功
                mExamFragmentCallback?.preFaceMatchingSuccess()
            }
            TYPE_END_EXAM -> {
                // 考后人脸验证成功
                mExamFragmentCallback?.submitExam(true)
            }
        }
    }

    private var mExamFragmentCallback: ExamFragmentCallback? = null

    override fun onAttach(context: Context) {
        super.onAttach(context)
        if (context is ExamFragmentCallback) {
            this.mExamFragmentCallback = context
        }
    }

    override fun onDetach() {
        this.mExamFragmentCallback = null
        super.onDetach()
    }

    private fun pretreatmentError(throwable: Throwable): Boolean {
        if (throwable is NetException) {
            // 600- 签到&签出已超时，请重新刷卡重试！
            if ("600" == throwable.code) {
                AlertDialog.Builder(requireContext())
                    .setTitle("提示")
                    .setMessage(throwable.message)
                    .setPositiveButton("确定") { _, _ ->
                        callLearnLoginApi {
                            faceEngineHelper?.stopPreview(false)
                        }
                    }.show()
                return true
            } else if ("500" == throwable.code &&
                true == throwable.message?.startsWith("人脸对比不符")
            ) {
                // 500- 人脸对比不符！
                AlertDialog.Builder(requireContext())
                    .setCancelable(false)
                    .setTitle("提示")
                    .setMessage(throwable.message)
                    .setPositiveButton("确定") { _, _ ->
                        faceEngineHelper?.stopPreview(false)
                    }.show()
                return true
            }
        }
        return false
    }

    private fun callLearnLoginApi(realLogin: Boolean = false, callback: () -> Unit) {
        val defUsername = ExamApp.sLearnLoginVo?.username
        val username = requireArguments().getString("username") ?: defUsername
        if (username.isNullOrEmpty()) {
            ExamApp.sLearnLoginVo = null
            HttpClient.token = null

            CommonUtils.restartApp(requireActivity())
            return
        }

        showLoading("查询中...")
        val disposable = ApiRepository.learnLogin(username, CommonUtils.getAndroidId(requireContext()), realLogin,"1")
            .subscribe({ data ->
                dismissLoading()
                ExamApp.sLearnLoginVo = data
                callback.invoke()
            }, { throwable ->
                dismissLoading()
                throwable.printStackTrace()
                showNetError(throwable)
            })
        addDisposable(disposable)
    }

    override fun onCompareSuccess() {
    }

    override fun onError(errMsg: String, type: FaceEngineHelper.OperType) {
    }

//    private fun alertAialogMsg(msg:String) {
//        val alertAialog: AlertDialog
//        val builder: AlertDialog.Builder = AlertDialog.Builder(requireContext())
//            .setTitle("用户操作")
//            .setMessage(msg)
//            .setPositiveButton("确认", DialogInterface.OnClickListener { dialog, which ->
//                dialog.dismiss() // 关闭对话框
//                callLearnLoginApi(true){}
//            }) // 添加取消按钮
//            .setNegativeButton("取消",
//                DialogInterface.OnClickListener { dialog, which -> // 点击取消，对话框消失
//                    dialog.dismiss()
//                })
//        alertAialog = builder.create()
//        alertAialog.show()
//    }
}