package com.hh.lib_face;

import static com.hh.lib_base.Constants.LogcatValue.LOG_NODE_FACE;
import static com.hh.lib_base.Constants.LogcatValue.WARP;

import android.content.Context;
import android.os.Bundle;

import com.alibaba.fastjson.JSONObject;
import com.alipay.arome.aromecli.AromeServiceInvoker;
import com.alipay.iot.bpaas.api.BPaaSApi;
import com.alipay.iot.bpaas.api.BPaaSInitCallback;
import com.alipay.iot.bpaas.api.InnerApi;
import com.alipay.iot.bpaas.api.service.BPaaSCallback;
import com.alipay.iot.bpaas.api.service.BPaaSResponse;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.hh.lib_ampe.bean.BaseAmpeRequestBean;
import com.hh.lib_ampe.utils.AromeInvoker;
import com.hh.lib_ampe.utils.MyTypeToken;
import com.hh.lib_base.BaseApplication;
import com.hh.lib_base.Constants;
import com.hh.lib_base.bean.ampe.BaseAmpeAppletResultBean;
import com.hh.lib_base.bean.device.DeviceConfigResultBean;
import com.hh.lib_base.log.AppLogUtils;
import com.hh.lib_base.log.UploadLogUtils;
import com.hh.lib_base.utils.GsonUtils;
import com.hh.lib_base.utils.StringUtils;
import com.hh.lib_base.utils.device.DeviceUtils;
import com.hh.lib_common.CardOrCodeEnum;
import com.hh.lib_common.event.FillLightEvent;
import com.hh.lib_face.bean.AlipayUserInfoRequestBean;
import com.hh.lib_face.bean.AlipayUserInfoResultBean;
import com.hh.lib_base.ConfigData;
import com.hh.lib_face.bean.BizContentBean;
import com.hh.lib_face.bean.InvokeScanFaceBean;
import com.hh.lib_face.bean.ParamsFaceBean;
import com.hh.lib_face.bean.ParamsFaceResultBean;
import com.hh.lib_face.bean.StartReadyBpaasServiceBean;
import com.hh.lib_face.bean.ThreeElementsBean;
import com.hh.lib_face.event.AlipayUserInfoRequestEvent;
import com.hh.lib_face.storageface.ZfbBPaaSOpenRocketUtils;
import com.hh.lib_face.storageface.bean.BPaaSOpenRocketBean;
import com.hh.lib_face.utils.BPaaSApiCommonUtils;
import com.hh.lib_face.utils.IdCardUtils;
import com.hh.lib_face.view.IDCardView;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONException;

import java.util.HashMap;
import java.util.Map;

/**
 * Description: 刷脸功能调用
 * @author xwh
 * time 2024/8/23
 * TODO 主要逻辑：startZfbBpaasService
 **/
public class BPaaSApiInvoker {

    private volatile static BPaaSApiInvoker bPaaSApiInvoker;
    private BPaaSApiResultStateListener bPaaSApiResultStateListener;

    HashMap<String, BaseAmpeRequestBean> ampeActionMap = new HashMap<>();

    private boolean isRepeatedStartBPaasVerifyID = false;  //是否已经重复调用重启刷脸服务

    private CardOrCodeEnum cardOrCodeEnum = CardOrCodeEnum.DeFAULT;

    private static final int GET_FACE_INFO_DELAY_TIME = 2000;    // 刷脸小程序指令防抖
   // private long getFaceInfoActionLastTime = 0;

    private IDCardView idCardView=null; //手动输入身份证View

    private  static HashMap<String, Long> actionRepeatFilterMap = new HashMap<>();  //重复命令过滤，上一次时间MAP


    /**
     *
     * @author xwh
     * Time 2024/8/27
     * Description: 刷脸功能交互入口
     *
    **/
    public void onCalled(Context context,BaseAmpeRequestBean dataBean, AromeServiceInvoker.BridgeCallback bridgeCallback) {
        if (dataBean == null) {
            return;
        }
        if (isActionrepeatFilter(dataBean, bridgeCallback)) {
            return;
        }
        if(isUnEnabledHardware(dataBean,bridgeCallback)){
            return;
        }

        switch (dataBean.getAction()) {
            case Constants.Ampe.ACTION_INIT_FACE: //TODO 初始化刷脸
                initAbcpFace(dataBean);
                break;
            case Constants.Ampe.ACTION_FACE:  //TODO 刷脸 1:N
                BaseAmpeRequestBean<ParamsFaceBean> newFaceBean=MyTypeToken
                        .toBaseAmpeRequestBean(dataBean,ParamsFaceBean.class);
                cardOrCodeEnum = CardOrCodeEnum.FACE;
                if(newFaceBean!=null){
                    newFaceBean.setBridgeCallback(bridgeCallback);
                }
                getAmpeActionMap().put(Constants.Ampe.ACTION_FACE, newFaceBean);
                ParamsFaceBean faceBean =   newFaceBean.getParams();;
                if (faceBean != null) {
                    ConfigData.serviceId = faceBean.getServiceId();
                    ConfigData.scope = faceBean.getScope();
                    ConfigData.query = faceBean.getQuery();
                }
                // 获取启动Bpaas刷脸的参数
                StartReadyBpaasServiceBean bpaasServiceBean = BPaaSApiCommonUtils.getInstance()
                        .getStartReadyBpaasServiceBean();
                invokeScanFace(bpaasServiceBean);
                break;
            case Constants.Ampe.ACTION_FACE_PERSONCARD:  // TODO 1:1 PersonCard
                BaseAmpeRequestBean<ParamsFaceBean> newPersonCardBean=MyTypeToken
                        .toBaseAmpeRequestBean(dataBean,ParamsFaceBean.class);
                cardOrCodeEnum = CardOrCodeEnum.PERSONCARD;
                if(newPersonCardBean!=null){
                    newPersonCardBean.setBridgeCallback(bridgeCallback);
                }
                getAmpeActionMap().put(Constants.Ampe.ACTION_FACE_PERSONCARD, newPersonCardBean);
                ParamsFaceBean personcardBean =  newPersonCardBean.getParams();
                if (personcardBean == null) {
                    AlipayUserInfoResultBean resultBean = new AlipayUserInfoResultBean();
                    resultBean.setFailed(true);
                    resultBean.setFailedMsg("入参参数错误！");
                    showAlipayUserInfoResult(resultBean);
                    return;

                }
                invokePersonCard(personcardBean.getCertName()
                        , personcardBean.getCertNo()
                        , personcardBean.getCertPhotoBase64Str());
                break;
            case Constants.Ampe.ACTION_ENTERIDNUMBER:   // TODO 手动输入身份证，公安网返回再1:1
                if (idCardView != null && idCardView.isAttachedToWindow()) {
                    return;
                }
                cardOrCodeEnum = CardOrCodeEnum.ENTERIDNUMBER;
                getAmpeActionMap().put(Constants.Ampe.ACTION_ENTERIDNUMBER, dataBean);
                idCardView = new IDCardView(context, dataBean);
                break;
            case Constants.Ampe.ACTION_STORAGE_FACE_INFO:  //TODO 老年食堂
                BaseAmpeRequestBean<BPaaSOpenRocketBean> newDoStorageBean=MyTypeToken
                        .toBaseAmpeRequestBean(dataBean,BPaaSOpenRocketBean.class);
                BPaaSOpenRocketBean startBPaaSOpenRocketBean = newDoStorageBean.getParams();
                if (startBPaaSOpenRocketBean == null) {
                    ZfbBPaaSOpenRocketUtils.getInstance().sendBridgeCallback(dataBean, new JSONObject(), false, "参数出错！");
                    return;
                }

                try {
                    startBPaaSOpenRocketBean.setZolozConfig(BPaaSApiCommonUtils.getInstance().getHardWareConfig());
                } catch (JSONException e) {
                    AppLogUtils.e(e.toString());
                }
                startBPaaSOpenRocketBean.setD2Config(BPaaSApiCommonUtils.getInstance().getD2Config());
                ConfigData.mRocketSessionId = ZfbBPaaSOpenRocketUtils.getInstance().startZfbBpaasOpenRocketService(dataBean);
                break;
            case Constants.Ampe.ACTION_SCAN_FACE:
                // 刷脸——江西（仅他一家的处理），后期不在维护
                break;
        }
    }

    /**
     *
     * @author xwh
     * Time 2024/9/26
     * Description: 是否未开启该模块
     * @return true:是该模块的消息并且未启用该模块
    **/
    private boolean isUnEnabledHardware(BaseAmpeRequestBean dataBean, AromeServiceInvoker.BridgeCallback bridgeCallback) {
        DeviceConfigResultBean configResultBean = ConfigData.getDeviceConfigResultBean();
        boolean isUseAlipayFace = true;
        boolean manualInIdCard = false;
        if (configResultBean != null) {
            isUseAlipayFace = configResultBean.isUseAlipayFace();
            manualInIdCard=configResultBean.isManualInIdCard();
        }
        String action = dataBean.getAction();
        if (!manualInIdCard && action != null && Constants.Ampe.ACTION_ENTERIDNUMBER.equals(action)) {
            AromeInvoker.getAromeInvoker().hardwareNotEnabled(dataBean, bridgeCallback);
            return true;
        }
        if (!isUseAlipayFace &&
                action != null &&
                (Constants.Ampe.ACTION_INIT_FACE .equals(action)  ||
                        Constants.Ampe.ACTION_FACE.equals(action)||
                        Constants.Ampe.ACTION_FACE_PERSONCARD.equals(action) ||
                        Constants.Ampe.ACTION_STORAGE_FACE_INFO.equals(action))) {
            AromeInvoker.getAromeInvoker().hardwareNotEnabled(dataBean, bridgeCallback);
            return true;
        }

        return false;
    }


    /**
     *
     * @author xwh
     * Time 2024/8/26
     * Description: 调用刷脸服务 1:N
     *
     **/
    public void invokeScanFace(StartReadyBpaasServiceBean bpaasServiceBean) {
        AppLogUtils.e("invokeScanFace");
        AppLogUtils.e("补光灯开启");
        EventBus.getDefault().post(new FillLightEvent(true));

        Map<String, Object> params = new HashMap<>();
        params.put("checkWay", "scanFace");
        invoke(params, ConfigData.mSessionId);
    }


    /**
     *
     * @author xwh
     * Time 2024/8/26
     * Description: 调用 1: 1人证比对服务
     *
    **/
    public void invokePersonCard(String certName, String certNo, String certPhotoBase64Str) {
        AppLogUtils.e("invokePersonCard---certName:" + certName + "---certNo:" + certNo + "---certPhotoBase64Str:" + certPhotoBase64Str);
        AppLogUtils.e("补光灯开启");
        // 补光灯开启
       EventBus.getDefault().post(new FillLightEvent(true));
        Map<String, Object> params = new HashMap<>();
        params.put("checkWay", "personCard");
        params.put("certNo", certNo);
        params.put("certName", certName);
        params.put("certPhotoBase64Str", certPhotoBase64Str);
        //参见 3.2.5
        invoke(params, ConfigData.mSessionId);
    }


    /**
     *
     * @author xwh
     * Time 2024/8/26
     * Description: 初始化刷脸
     * @param requestBean requestBean=null:第一次请求接口配置后初始化刷脸服务，入参为null
    **/
    public void initAbcpFace(final BaseAmpeRequestBean requestBean) {
        Bundle extInfo = new Bundle();
        extInfo.putLong(BPaaSApi.KEY_EXT_TIME_OUT, 2 * 60 * 600);

        // test1
//        extInfo.putString("scopes", "auth_user,order_service");

        // MachineAppId 对应 abcpAppId

        StringBuilder logContentSb = new StringBuilder();
        logContentSb.append("APP_ID = ").append(ConfigData.getDeviceConfigResultBean().getAbcpAppId())
                .append(WARP).append("APP_VERION = ").append(ConfigData.appVersionBPaaS)
                .append(WARP).append("extInfo = ").append(GsonUtils.getGson().toJson(extInfo));
        String logLine = (new Throwable().getStackTrace())[0].toString();
        UploadLogUtils.sendLogs("刷脸初始化", "-----abcp--BPaaSApi", logLine, logContentSb.toString());

        BPaaSApi.getInstance().init(BaseApplication.getContext(), ConfigData.getDeviceConfigResultBean().getAbcpAppId(), ConfigData.appVersionBPaaS, extInfo,
                new BPaaSInitCallback() {
                    @Override
                    public void onSuccess() {
                        AppLogUtils.e("init--FACE--onSuccess");
                        if (bPaaSApiResultStateListener != null) {
                            bPaaSApiResultStateListener.onInitBpaaSSuccess();
                        }
                        InnerApi.removeIpcListener(BPaaSApiCommonUtils.getInstance().mIpcListener);
                        //添加IpcListener,用于监听与刷脸smile的连接,便于业务自愈
                        InnerApi.addIpcListener(BPaaSApiCommonUtils.getInstance().mIpcListener);

                        String logLine = (new Throwable().getStackTrace())[0].toString();
                        UploadLogUtils.sendLogs("刷脸初始化成功", "----BPaaSApi--init---onSuccess---", logLine, "");
                        if (requestBean != null) { //TODO 配置接口请求成功后，先自动初始化刷脸服务
                            sendInitFaceMessage(requestBean, "", requestBean.getBridgeCallback());
                        }
                        // 获取启动Bpaas刷脸的参数
                        StartReadyBpaasServiceBean bpaasServiceBean = BPaaSApiCommonUtils.getInstance().getStartReadyBpaasServiceBean();
                        //启动核身服务
                        startZfbBpaasService(bpaasServiceBean);
                    }

                    @Override
                    public void onFail(String errorMessage) {
                        // E69003
                        String logLine = (new Throwable().getStackTrace())[0].toString();
                        UploadLogUtils.sendLogs("刷脸初始化失败", "----BPaaSApi--init--onFail---", logLine, errorMessage);
                    }
                });
    }


    /**
     *
     * @author xwh
     * Time 2024/8/26
     * Description: 启动刷脸服务
     *
    **/
    public void startZfbBpaasService(final StartReadyBpaasServiceBean bpaasServiceBean) {
        String logLine = (new Throwable().getStackTrace())[0].toString();
        if (bpaasServiceBean == null) {
            UploadLogUtils.sendLogs("startBpaasService---入参", "", logLine, "入参出错-bpaasServiceBean！！！");
            return;
        }
        Bundle params = BPaaSApiCommonUtils.getInstance().startBpaasServiceparameter(bpaasServiceBean);
        if(params==null){
            UploadLogUtils.sendLogs("startBpaasService---入参", "", logLine, "入参出错-Bundle！！！");
            return;
        }

        StringBuilder logContentSb = new StringBuilder();
        logContentSb.append("params = ").append(params.toString()).append(WARP)
                .append("StartBpaasServiceBean = ").append(bpaasServiceBean.toString());
        UploadLogUtils.sendLogs("startBpaasService---入参", "", logLine, logContentSb.toString());

        String mSessionId = BPaaSApi.getInstance().startBPaaSService(ConfigData.getDeviceConfigResultBean().getAbcpAppId(),
                "BPaasVerifyID", params, new BPaaSCallback() {
                    @Override
                    public void onResponse(BPaaSResponse bPaaSResponse) {
                        AppLogUtils.e("BPaaSApi--startBpaasService--onResponse = " + bPaaSResponse);
                        // {code=1000, subCode='E00000', subMsg='成功(E00000)', mResult='Bundle[mParcelledData.dataSize=124]', extInfo={}}
                        // code=1001, subCode='E69009', subMsg='未初始化成功，请先初始化(E69009)  注意检测getHardWareConfig
                        // {code=1001, subCode='E60001', subMsg='flow eval error', mResult='null', extInfo={}}
                        int code = bPaaSResponse.getCode();
                        AppLogUtils.e("BPaaSApi--startBpaasService--onResponse--Code = " + code);
                        EventBus.getDefault().post(new FillLightEvent());  //关闭补光灯
                        // 重新唤起
                        invokeResume();
                        String logLine = (new Throwable().getStackTrace())[0].toString();
                        StringBuilder logContentSb = new StringBuilder();
                        logContentSb.append("code = ").append(code).append(WARP)
                                .append("onResponse = ").append(bPaaSResponse);
                        UploadLogUtils.sendLogs("startBpaasService---onResponse", "", logLine, logContentSb.toString());

                        // 1000表示超时（已经刷脸成功拿到其他信息，但是还没有做其他处理，导致20s超时）
                        // 1004smile异常
                        if (code == 1004) {
                            //重新启动核点服务
                            startZfbBpaasService(bpaasServiceBean);
                        } else if (code == 1001) {
                            // BPaaSResponse{code=1001, subCode='E60001', subMsg='flow eval error', mResult='null', extInfo={}}
                        }

                        if (!isRepeatedStartBPaasVerifyID && //避免循环调用
                                bPaaSResponse != null &&
                                ("E69013".equals(bPaaSResponse.getSubCode())
                                        || "E69010".equals(bPaaSResponse.getSubCode()))) {
                            try {
                                isRepeatedStartBPaasVerifyID = true; //大多数情况重启一次无反应没必要循环重启了
                                //重新启动核点服务
                                startZfbBpaasService(bpaasServiceBean);
                            } catch (Exception e) {
                                AppLogUtils.e(e.toString());
                            }

                        } else if (bPaaSResponse != null &&
                                !"E69013".equals(bPaaSResponse.getSubCode()) &&
                                !"E69010".equals(bPaaSResponse.getSubCode())) {
                            //Todo 当SubCode!="E69013"和”E69010“,字段复位，为下次做准备
                            isRepeatedStartBPaasVerifyID = false;
                        } else {
                            //Todo 已经循环调用过一次了，且还是"E69013"、”E69010“,
                        }
                    }

                    @Override
                    public void onEvent(String bPaasVerifyID, String resultStr, Bundle bundle) {
                        // {"alipayUid":"","code":2006,"extInfo":"{\"authCode\":\"\"}","ftoken":"fp11d8fef76c02372e78fe3169cbde9ch72","isvResult":true,"subCode":"Z1208","subMessage":"抱歉，无法认出你(Z1208)","vid":""}
                        // 刷脸成功返回的数据
                        AppLogUtils.e("BPaaSApi--startBpaasService--onEvent,bPaasVerifyID: " + bPaasVerifyID+
                                (bundle==null?"":"bundle = " + GsonUtils.getGson().toJson(bundle))+
                                "resultStr:" + resultStr);
                        AppLogUtils.e("补光灯关闭");
                        EventBus.getDefault().post(new FillLightEvent());
                        if(bPaaSApiResultStateListener!=null){
                            bPaaSApiResultStateListener.onFaceResult(resultStr+"");
                        }

                        String logLine = (new Throwable().getStackTrace())[0].toString();
                        StringBuilder logContentSb = new StringBuilder();
                        logContentSb.append("onEvent = ").append(WARP)
                                .append("resultStr = ").append(resultStr).append(WARP)
                                .append("bPaasVerifyID = ").append(bPaasVerifyID).append(WARP)
                                .append("bundle = ").append(GsonUtils.getGson().toJson(bundle));

                        UploadLogUtils.sendLogs("刷脸返回数据","onEvent",logLine,logContentSb.toString());
                        // 将resultStr转成json
                        InvokeScanFaceBean invokeScanFaceBean = GsonUtils.getGson().fromJson(resultStr, InvokeScanFaceBean.class);
                        if (invokeScanFaceBean.getCode() == 0) {
                            //{"action":"getFaceInfo","data":{"originFaceInfo":"{\"messageType\":\"hdMiddleType\",\"messageContent\":\"{\\\"stauts\\\":\\\"HD_SMILE_WAKE\\\"}\"}"},"event":"open","message":"{\"messageType\":\"hdMiddleType\",\"messageContent\":\"{\\\"stauts\\\":\\\"HD_SMILE_WAKE\\\"}\"}","success":false,"taskId":"2"}
                            //TODO 返回的数据类似于日志
                            return;
                        }
                        AppLogUtils.e("invokeScanFaceBean.getCode() = " + invokeScanFaceBean.getCode());
                        // 重新唤起
                        invokeResume();
                        BaseAmpeRequestBean<ParamsFaceBean> ampeActionDataBean = null;
                        String action = "";
                        if(cardOrCodeEnum==CardOrCodeEnum.PERSONCARD){
                            //1:1
                            action = Constants.Ampe.ACTION_FACE_PERSONCARD;
                            ampeActionDataBean = getAmpeActionMap().get(action);

                        }else if(cardOrCodeEnum==CardOrCodeEnum.ENTERIDNUMBER){
                            //1:1
                            action = Constants.Ampe.ACTION_ENTERIDNUMBER;
                            ampeActionDataBean = getAmpeActionMap().get(action);
                        }else if(cardOrCodeEnum==CardOrCodeEnum.FACE){
                            // 是1:N
                            action = Constants.Ampe.ACTION_FACE;
                            ampeActionDataBean = getAmpeActionMap().get(action);
                        }

                        if (ampeActionDataBean == null) {
                            AppLogUtils.e("ampeActionDataBean == null");
                            return;
                        }
                        AromeServiceInvoker.BridgeCallback bridgeCallback = ampeActionDataBean.getBridgeCallback();

                        BaseAmpeAppletResultBean<ParamsFaceResultBean> ampeAppletResultBean = new BaseAmpeAppletResultBean();
                        ampeAppletResultBean.setAction(action);
                        ampeAppletResultBean.setEvent(ampeActionDataBean.getEvent());
                        ampeAppletResultBean.setTaskId(ampeActionDataBean.getTaskId());
                        DeviceConfigResultBean configResultBean=ConfigData.getDeviceConfigResultBean();
                        if (invokeScanFaceBean.getCode() == 1000){
                            // 人证还是刷脸，判断三要素，
                            // 刷脸
                            if (cardOrCodeEnum ==CardOrCodeEnum.FACE || cardOrCodeEnum==CardOrCodeEnum.PERSONCARD) {
                                // 根据配置是否请求用户信息三要素
                                boolean appGetUserInfo = false;
                                if(configResultBean!=null){
                                    appGetUserInfo=configResultBean.isAppGetUserInfo();
                                }
                                AppLogUtils.e("appGetUserInfo = " + appGetUserInfo);
                                if (appGetUserInfo) {
                                    AlipayUserInfoRequestBean alipayUserInfoRequestBean = GsonUtils.getGson().fromJson(resultStr, AlipayUserInfoRequestBean.class);
                                    alipayUserInfoRequestBean.setServiceAddress(configResultBean.getServiceAddress());
                                    alipayUserInfoRequestBean.setSn(DeviceUtils.getDeviceSN());
                                    alipayUserInfoRequestBean.setAppId(configResultBean.getServiceAppId());
                                    String certName="";
                                    String certNo="";
                                    if(ampeActionDataBean.getParams()!=null){
                                        certNo =  ampeActionDataBean.getParams().getCertNo();
                                        certName= ampeActionDataBean.getParams().getCertName();
                                    }
                                    AlipayUserInfoRequestEvent event=new AlipayUserInfoRequestEvent(alipayUserInfoRequestBean,
                                            certNo,certName);
                                    //通过接口获取三要素接口请求
                                    EventBus.getDefault().post(event);
                                    String logLineUserInfo = (new Throwable().getStackTrace())[0].toString();
                                    StringBuilder logContentSbUserInfo = new StringBuilder();
                                    logContentSbUserInfo.append("alipayUserInfoRequestBean = ").append(alipayUserInfoRequestBean.toString());
                                    UploadLogUtils.sendLogs("用户信息三要素---入参---",action,logLineUserInfo,logContentSbUserInfo.toString());
                                }else {
                                    ampeAppletResultBean.setSuccess(true);
                                    ampeAppletResultBean.setMessage("成功");
                                    ParamsFaceResultBean data=null;
                                    try {
                                        data = GsonUtils.getGson().fromJson(resultStr, ParamsFaceResultBean.class);
                                    }catch (Exception e){
                                        AppLogUtils.e(e.toString());
                                    }
                                    if(data==null){
                                        data=new ParamsFaceResultBean();
                                    }

                                    data.setOriginFaceInfo(resultStr);
                                    ampeAppletResultBean.setData(data);

                                    // 回传处理结果给小程序
                                    try {
                                        JsonObject jsonObject = GsonUtils.getGson().toJsonTree(ampeAppletResultBean).getAsJsonObject();
                                        if (bridgeCallback != null) {
                                            bridgeCallback.callback(jsonObject.toString());
                                        }
                                        String logLine11 = (new Throwable().getStackTrace())[0].toString();
                                        StringBuilder logContentSb11 = new StringBuilder();
                                        logContentSb11.append("jsonObject = ").append(jsonObject).append(WARP)
                                                .append("appGetUserInfo = ").append(appGetUserInfo);
                                            UploadLogUtils.sendLogs("--刷脸--支付宝结果--回传处理结果给小程序--",
                                                action,logLine11,logContentSb11.toString());

                                    } catch (Throwable t) {
                                        AppLogUtils.e("onCalled--t" + t);
                                    }
                                }
                            } else if (cardOrCodeEnum==CardOrCodeEnum.ENTERIDNUMBER) {

                                ampeAppletResultBean.setSuccess(true);
                                ampeAppletResultBean.setMessage("成功");
                                ParamsFaceResultBean data=null;
                                try {
                                    data = GsonUtils.getGson().fromJson(resultStr, ParamsFaceResultBean.class);
                                }catch (Exception e){
                                    AppLogUtils.e(e.toString());
                                }
                                if(data==null){
                                    data=new ParamsFaceResultBean();
                                }
                                data.setOriginFaceInfo(resultStr);
                                String certName="";
                                String certNo="";
                                if(ampeActionDataBean.getParams()!=null){
                                    certNo =  ampeActionDataBean.getParams().getCertNo();
                                    certName= ampeActionDataBean.getParams().getCertName();
                                }
                                data.setIdNum(certNo);
                                data.setName(certName);
                                ampeAppletResultBean.setData(data);
                                // 回传处理结果给小程序
                                try {
                                    JsonObject jsonObject = GsonUtils.getGson().toJsonTree(ampeAppletResultBean).getAsJsonObject();
                                    AppLogUtils.e("人证比对数据返回  " + new Gson().toJson(jsonObject));
                                    if (bridgeCallback != null) {
                                        bridgeCallback.callback(jsonObject.toString());
                                    }
                                    // 日志内容
                                    StringBuilder logContentSb11 = new StringBuilder();
                                    logContentSb11.append("jsonObject = ").append(jsonObject).append(WARP);
                                    String logLine11 = (new Throwable().getStackTrace())[0].toString();
                                    UploadLogUtils.sendLogs("手输证件号--支付宝结果--回传处理结果给小程序--",
                                            Constants.Ampe.ACTION_ENTERIDNUMBER,logLine11,logContentSb11.toString());
                                } catch (Throwable t) {
                                    AppLogUtils.e("onCalled--t" + t);
                                }
                            }


                        } else {
                            // onEvent非1000
                            AppLogUtils.e("onEvent非1000");
                            ampeAppletResultBean.setSuccess(false);
                            ampeAppletResultBean.setMessage(resultStr);
                            ParamsFaceResultBean data=new ParamsFaceResultBean();
                            data.setOriginFaceInfo(resultStr);
                            ampeAppletResultBean.setData(data);

                            // 回传处理结果给小程序
                            try {
                                JsonObject jsonObject = GsonUtils.getGson().toJsonTree(ampeAppletResultBean).getAsJsonObject();

                                if (bridgeCallback != null) {
                                    bridgeCallback.callback(jsonObject.toString());
                                }

                                String logLine11 = (new Throwable().getStackTrace())[0].toString();
                                StringBuilder logContentSb11 = new StringBuilder();
                                logContentSb11.append("jsonObject = ").append(jsonObject).append(WARP);
                                UploadLogUtils.sendLogs("--刷脸--支付宝结果--回传处理结果给小程序--",
                                        action,logLine11,logContentSb11.toString());

                            } catch (Throwable t) {
                                AppLogUtils.e("onCalled--t" + t);
                            }


                            if (invokeScanFaceBean.getCode() == 1001) {
                                //

                            } else if (invokeScanFaceBean.getCode() == 2006) {
                                // 无法认出

                            }
                        }
                    }
        });

        ConfigData.mSessionId = mSessionId;
        AppLogUtils.e("startBpaasService--mSessionId = " + mSessionId);


    }


    /**
     *
     * @author xwh
     * Time 2024/8/28
     * Description: 通过公安网获取三要素
     *
    **/
    public void threeElementsContractResult(final ThreeElementsBean threeElementsBean) {
        if (idCardView != null) {
            idCardView.release();
            idCardView = null;
        }
        DeviceConfigResultBean deviceConfigBean = ConfigData.getDeviceConfigResultBean();
        if (deviceConfigBean == null) {
            return;
        }
        String bizContent = IdCardUtils.decrypt(
                deviceConfigBean.getManualInIdCardAuth().getPrivateKey(),
                threeElementsBean.getBizContent());
        BizContentBean bizContentBean = new Gson().fromJson(bizContent, BizContentBean.class);
        AppLogUtils.i("接口换取三要素返回", "国密解密内容  " + bizContent);
        cardOrCodeEnum = CardOrCodeEnum.ENTERIDNUMBER;
        BaseAmpeRequestBean<ParamsFaceBean> dataBean = getAmpeActionMap().get(Constants.Ampe.ACTION_ENTERIDNUMBER);
        if (dataBean == null) {
            return;
        }
        if(bizContentBean == null){
            String logLine = (new Throwable().getStackTrace())[0].toString();
            UploadLogUtils.sendLogs("接口换取三要素","",logLine,"未配置密钥，授权平台配置出错！ ");
            return;
        }
        ParamsFaceBean personcardBean = new ParamsFaceBean();
        personcardBean.setCertName(bizContentBean.getXm());
        personcardBean.setCertNo(bizContentBean.getSfzh());
        dataBean.setParams(personcardBean);
        getAmpeActionMap().put(Constants.Ampe.ACTION_ENTERIDNUMBER, dataBean);
        invokePersonCard(bizContentBean.getXm(), bizContentBean.getSfzh(),
                bizContentBean.getXp());

    }

    /**
     *
     * @author xwh
     * Time 2024/8/26
     * Description: 刷脸后通过接口获取三要素
     *
    **/
    public void showAlipayUserInfoResult(AlipayUserInfoResultBean alipayUserInfoBeanData){
        AppLogUtils.e("showAlipayUserInfoResult--" + alipayUserInfoBeanData.toString());
        BaseAmpeRequestBean<ParamsFaceBean> ampeActionDataBean = null;
        String action = "";
        if(cardOrCodeEnum==CardOrCodeEnum.PERSONCARD){
            //1:1
            action = Constants.Ampe.ACTION_FACE_PERSONCARD;
            ampeActionDataBean = getAmpeActionMap().get(action);

        }else if(cardOrCodeEnum==CardOrCodeEnum.FACE){
            // 是1:N
            action = Constants.Ampe.ACTION_FACE;
            ampeActionDataBean = getAmpeActionMap().get(action);
        }

        if (ampeActionDataBean == null) {
            AppLogUtils.e("ampeActionDataBean == null");
            return;
        }

        AromeServiceInvoker.BridgeCallback bridgeCallback = ampeActionDataBean.getBridgeCallback();
        BaseAmpeAppletResultBean<ParamsFaceResultBean> bean = new BaseAmpeAppletResultBean<ParamsFaceResultBean>();
        bean.setAction(action);
        bean.setEvent(ampeActionDataBean.getEvent());
        bean.setTaskId(ampeActionDataBean.getTaskId());
        if(alipayUserInfoBeanData.isFailed()){
            bean.setSuccess(false);
            bean.setMessage(alipayUserInfoBeanData.getFailedMsg());
        }else {
            bean.setSuccess(true);
            bean.setMessage("成功");
            ParamsFaceResultBean data=new ParamsFaceResultBean();
            data.setIdNum(alipayUserInfoBeanData.getIdNum());
            data.setName(alipayUserInfoBeanData.getName());
            data.setUserId(alipayUserInfoBeanData.getUserId());
            data.setMobile(alipayUserInfoBeanData.getMobile());
            data.setAvatar(alipayUserInfoBeanData.getAvatar());
            data.setPhotoBase64(alipayUserInfoBeanData.getPhotoBase64());
            bean.setData(data);
        }
        // 回传处理结果给小程序
        try {
            JsonObject jsonObject = GsonUtils.getGson().toJsonTree(bean).getAsJsonObject();

            if (bridgeCallback != null) {
                bridgeCallback.callback(jsonObject.toString());
            }
            String logLine = (new Throwable().getStackTrace())[0].toString();
            StringBuilder logContentSb = new StringBuilder();
            logContentSb.append("jsonObject = ").append(jsonObject);

            UploadLogUtils.sendLogs("刷脸--用户三要素--回传处理结果给小程序--",action,logLine,logContentSb.toString());
        } catch (Throwable t) {
            AppLogUtils.e("onCalled--t" + t);
        }
    }

    /**
     *
     * @author xwh
     * Time 2024/8/26
     * Description: 刷脸初始化成功回调
     *
     **/
    private void sendInitFaceMessage(BaseAmpeRequestBean dataBean,
                                     String msg,
                                     AromeServiceInvoker.BridgeCallback bridgeCallback) {
        BaseAmpeAppletResultBean initFaceBean = new BaseAmpeAppletResultBean();
        initFaceBean.setAction(Constants.Ampe.ACTION_INIT_FACE);
        initFaceBean.setEvent(dataBean.getEvent());
        initFaceBean.setTaskId(dataBean.getTaskId());
        if (StringUtils.isNull(msg)) {
            initFaceBean.setSuccess(true);
            initFaceBean.setMessage("成功");
        } else {
            initFaceBean.setSuccess(false);
            initFaceBean.setMessage(msg);
        }
        // 回传处理结果给小程序
        try {
            JsonObject jsonObject = GsonUtils.getGson().toJsonTree(initFaceBean).getAsJsonObject();
            if (bridgeCallback != null) {
                bridgeCallback.callback(jsonObject.toString());
            }
            String logLine = (new Throwable().getStackTrace())[0].toString();
            StringBuilder logContentSbInitFace = new StringBuilder();
            logContentSbInitFace.append("jsonObject = ").append(jsonObject);
            UploadLogUtils.sendLogs(Constants.LogcatValue.LOG_NODE_APPLET + "刷脸",
                    Constants.Ampe.ACTION_INIT_FACE, logLine, logContentSbInitFace.toString());
        } catch (Throwable t) {
            AppLogUtils.e("onCalled--t" + t);
        }
    }

    /**
     *
     * @author xwh
     * Time 2024/8/26
     * Description: 重新唤起刷脸
     * 从使用角度看，类似于重置。
     *
     **/
    public void invokeResume() {
        Map<String, Object> params = new HashMap<>();
        params.put("action", "resume");

        // 日志开始----------------begin
        // 日志行数——对应web端"日志标签"
        String logLine = (new Throwable().getStackTrace())[0].toString();
        // 日志节点
        String logNode = LOG_NODE_FACE + "invokeResume---重新唤起刷脸---";
        // 日志内容
        StringBuilder logContentSb = new StringBuilder();
        logContentSb.append(logNode).append(WARP)
                .append("params = ").append(params.toString());
        UploadLogUtils.sendLogs("invokeResume---重新唤起刷脸---","",logLine,logContentSb.toString());
        //参见 3.2.5
        invoke(params, ConfigData.mSessionId);
    }


    /**
     *
     * @author xwh
     * Time 2024/8/26
     * Description: 调用刷脸功能
     * TODO 注意，最终数据是在 startBPaaSService->OnEvent中返回
     *
     **/
    public void invoke(Map<String, Object> params, String mSessionId) {
        AppLogUtils.e("invoke -- params = " + params.toString());
        AppLogUtils.e("invoke -- mSessionId = " + mSessionId);
        // 初始化Bpaas服务前先判断mSessionId
        if (mSessionId == null) {
            String logLine = (new Throwable().getStackTrace())[0].toString();
            UploadLogUtils.sendLogs("调用刷脸invoke---", "", logLine, "invoke, mSessionId is null");
            return;
        }
        if (params == null) {
            params = new HashMap<>();
        }


        params.put(BPaaSApi.KEY_BPAAS_IPC_TIME_OUT, -1L);

        AppLogUtils.e("invoke -- params = " + params.toString());

        // 打印用
        final Map<String, Object> paramsNew = params;

        BPaaSApi.getInstance().invoke(ConfigData.getDeviceConfigResultBean().getAbcpAppId(),
                "BPaasVerifyID", params, mSessionId, new BPaaSCallback() {
                    @Override
                    public void onResponse(BPaaSResponse bPaaSResponse) {
                        // 只要能刷脸就会在这里，但刷脸的authcode和ftoken要到onEvent中拿
                        int code = bPaaSResponse.getCode();
                        String logLine = (new Throwable().getStackTrace())[0].toString();
                        StringBuilder logContentSb = new StringBuilder();
                        logContentSb.append("params = ").append(paramsNew).append(WARP)
                                .append("code = ").append(code).append(WARP)
                                .append("bPaaSResponse = ").append(bPaaSResponse).append(WARP)
                                .append("bPaaSResponseJson = ")
                                .append(GsonUtils.getGson().toJson(bPaaSResponse)).append(WARP);
                        UploadLogUtils.sendLogs("刷脸invoke---onResponse---", code + "", logLine, logContentSb.toString());


                    }

                    @Override
                    public void onEvent(String id, String resultStr, Bundle bundle) {
                        AppLogUtils.e("---调用刷脸invoke--onEvent--id = " + id + "----resultStr = " + resultStr + "-- bundle = " + new Gson().toJson(bundle));
                        // {"alipayUid":"","code":1001,"extInfo":"{\"authCode\":\"\"}","isvResult":true,"subCode":"Z6136","subMessage":"没有认出你，请再试一次(Z6136)","vid":""}null
                        // {"alipayUid":"2088612116677214","code":1000,"extInfo":"{\"authCode\":\"b34a132e7650445eb9b254d5dd7dDD21\"}","ftoken":"fp103df6a4e88e2611591822c46101e3h91","isvResult":true,"subCode":"","subMessage":"","vid":""}-- bundle = null

                        InvokeScanFaceBean invokeScanFaceBean = new Gson().fromJson(resultStr, InvokeScanFaceBean.class);
                        AppLogUtils.e("补光灯关闭");
                        // 补光灯关闭
                        EventBus.getDefault().post(new FillLightEvent());
                        String logLine = (new Throwable().getStackTrace())[0].toString();
                        StringBuilder logContentSb = new StringBuilder();
                        logContentSb.append("id = ").append(id).append(WARP)
                                .append("resultStr = ").append(resultStr).append(WARP)
                                .append("bundle = ").append(new Gson().toJson(bundle));
                        UploadLogUtils.sendLogs("刷脸invoke---onEvent---", "" + invokeScanFaceBean.getCode(), logLine, logContentSb.toString());


                    }
                });
    }

    /**
     *
     * @author xwh
     * Time 2024/8/28
     * Description: 停止服务
     *
    **/
    public void stopBpaasService(String sessionId) {
        if (StringUtils.isNull(sessionId)) {
            return;
        }
        AppLogUtils.e("stopBpaasService--SessionId =" + sessionId);
        BPaaSApi.getInstance().stopBPaaSService(ConfigData.getDeviceConfigResultBean().getAbcpAppId(), "BPaasVerifyID", new Bundle(), sessionId, new BPaaSCallback() {
            @Override
            public void onResponse(BPaaSResponse bPaaSResponse) {
                AppLogUtils.e("停止回调onResponse");
                if (bPaaSResponse == null || bPaaSResponse.getCode() == BPaaSResponse.RESULT_CODE_FAIL) {
                    AppLogUtils.e("stopBPaaSService--onResponse--失败 stopBPaaSService bPaaSResponse=" + bPaaSResponse);
                    return;
                }
                String subCode = bPaaSResponse.getSubCode();
                int code = bPaaSResponse.getCode();
                AppLogUtils.e("stopBPaaSService--onResponse--成功 stopBPaaSService subCode=" + subCode + "code：" + code);
            }

            @Override
            public void onEvent(String s, String resultStr, Bundle bundle) {
                AppLogUtils.e("stopBPaaSService--onEvent--resultStr:" + resultStr);
            }
        });
    }

    public static BPaaSApiInvoker getInstance() {
        if (bPaaSApiInvoker == null) {
            synchronized (BPaaSApiInvoker.class) {
                if (bPaaSApiInvoker == null) {
                    bPaaSApiInvoker = new BPaaSApiInvoker();
                    initRepeatFilterMap();
                }
            }
        }
        return bPaaSApiInvoker;
    }

    public HashMap<String, BaseAmpeRequestBean> getAmpeActionMap() {
        if(ampeActionMap==null){
            synchronized (BPaaSApiInvoker.class){
                if(ampeActionMap==null){
                    ampeActionMap=new HashMap<>();
                }
            }
        }
        return ampeActionMap;
    }

    /**
     *
     * @author xwh
     * Time 2024/8/29
     * Description: 初始化需要过滤命令Map
     *
    **/
    private static void initRepeatFilterMap(){
        if(actionRepeatFilterMap==null){
            actionRepeatFilterMap=new HashMap<>();
        }
        actionRepeatFilterMap.put( Constants.Ampe.ACTION_FACE,0L); //初始化上一次时间为0
        actionRepeatFilterMap.put( Constants.Ampe.ACTION_FACE_PERSONCARD,0L);
        actionRepeatFilterMap.put( Constants.Ampe.ACTION_ENTERIDNUMBER,0L);
        actionRepeatFilterMap.put( Constants.Ampe.ACTION_STORAGE_FACE_INFO,0L);
    }

    /**
     *
     * @author xwh
     * Time 2024/8/29
     * Description: 命令重复过滤，目前主要防止:重启页面后,Ampe监听会叠加，相当于启动一次多一位观察者
     *
     **/
    private boolean isActionrepeatFilter(BaseAmpeRequestBean dataBean,AromeServiceInvoker.BridgeCallback bridgeCallback) {
        long curClickTime = System.currentTimeMillis();
        /*Constants.Ampe.ACTION_INIT_FACE.equals(dataBean.getAction())*/ //初始化不在里面是为了防止初始化成功后立马调用了刷脸
        boolean isFaceAction = Constants.Ampe.ACTION_FACE.equals(dataBean.getAction())
                || Constants.Ampe.ACTION_STORAGE_FACE_INFO.equals(dataBean.getAction())
                || Constants.Ampe.ACTION_FACE_PERSONCARD.equals(dataBean.getAction())
                || Constants.Ampe.ACTION_ENTERIDNUMBER.equals(dataBean.getAction());
        if (actionRepeatFilterMap == null) {
            return false;
        }
        Long lastTime = actionRepeatFilterMap.get(dataBean.getAction());  //上一次时间
        if (lastTime == null) {
            lastTime = 0L;
        }
        if (isFaceAction && ((curClickTime - lastTime) < GET_FACE_INFO_DELAY_TIME)) {
            BaseAmpeAppletResultBean ampeAppletResultBean = new BaseAmpeAppletResultBean();
            ampeAppletResultBean.setAction(dataBean.getAction());
            ampeAppletResultBean.setEvent(dataBean.getEvent());
            ampeAppletResultBean.setTaskId(dataBean.getTaskId());
            ampeAppletResultBean.setMessage("忽略2秒内重复调起-刷脸命令");
            ampeAppletResultBean.setSuccess(false);
            try {
              /*  JsonObject faceFailResult = GsonUtils.getGson().toJsonTree(ampeAppletResultBean).getAsJsonObject();

                if (bridgeCallback != null) {
                    bridgeCallback.callback(faceFailResult.toString());
                }*/
                //todo 上传日志，并且替换老的bridgeCallback，
                BaseAmpeRequestBean baseAmpeRequestBean= getAmpeActionMap().get(dataBean.getAction());
                if(baseAmpeRequestBean!=null){
                    baseAmpeRequestBean.setBridgeCallback(bridgeCallback);
                }
                getAmpeActionMap().put(dataBean.getAction(),baseAmpeRequestBean);
                String logLine = (new Throwable().getStackTrace())[0].toString();
                UploadLogUtils.sendLogs("刷脸返回数据", Constants.Ampe.ACTION_FACE, logLine, "忽略2秒内重复调起-刷脸命令");
                actionRepeatFilterMap.put(dataBean.getAction(), curClickTime);

            } catch (Exception e) {
                AppLogUtils.e(e.toString());
            }
            return true;
        }
        actionRepeatFilterMap.put(dataBean.getAction(), curClickTime);
        return false;
    }

    public void setbPaaSApiResultStateListener(BPaaSApiResultStateListener bPaaSApiResultStateListener) {
        this.bPaaSApiResultStateListener = bPaaSApiResultStateListener;
    }

    public void onRelease() {
        //关闭小程序
        if(StringUtils.isNotNull(ConfigData.mSessionId)){
            BPaaSApiInvoker.getInstance().stopBpaasService(ConfigData.mSessionId);
        }
        //关闭老年食堂小程序,老年食堂刷脸功能是一个小程序，会自动关闭，此处是避免有遗留没释放
        if(StringUtils.isNotNull(ConfigData.mRocketSessionId)){
            BPaaSApiInvoker.getInstance().stopBpaasService(ConfigData.mRocketSessionId);
        }
        ZfbBPaaSOpenRocketUtils.getInstance().onRelease();
        BPaaSApiCommonUtils.getInstance().onRelease();
        bPaaSApiInvoker = null;

    }
}
