package org.dromara.payment.worker.service.impl;

import com.tencentcloudapi.common.profile.ClientProfile;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.common.core.constant.MpContants;
import org.dromara.common.core.exception.base.BaseException;
import org.dromara.common.core.service.BaseService;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.payment.worker.domain.SysUnitDomain;
import org.dromara.payment.worker.domain.ThirdConf;
import org.dromara.payment.worker.service.IIdCardAndOtherService;
import org.dromara.system.api.RemoteConfigService;
import org.dromara.system.api.domain.RemoteSysUnitDomainVo;
import org.springframework.stereotype.Service;

import com.tencentcloudapi.common.AbstractModel;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.faceid.v20180301.FaceidClient;
import com.tencentcloudapi.faceid.v20180301.models.*;

import java.util.Map;

/**
 * @author sunzexing
 * @version 1.0
 * @title IdCardAndOtherServiceImpl
 * @description
 * @create 2024-04-28 16:36
 */
@Service
@Slf4j
public class TencentIdCardAndOtherServiceImpl extends BaseService implements IIdCardAndOtherService {


    @DubboReference
    private RemoteConfigService remoteConfigService;


    @Override
    public boolean cardId2(String name, String idCard, String code) throws Exception {
        ThirdConf tc =  this.getThirdConfig(code,"idcardAuthConfig");
        return this.cardId2(name,idCard,tc);
    }

    @Override
    public boolean bankCard4(String bankCard, String name, String phone, String idCard, String code) throws Exception {
        ThirdConf tc =  this.getThirdConfig(code,"bankCard4Config");
        return this.bankCard4(bankCard,name,phone,idCard,tc);
    }

    @Override
    public boolean bankCard3(String bankCard, String name, String idCard, String code) throws Exception {
        return this.bankCard4(bankCard,name,null,idCard,code);
    }

    @Override
    public boolean cardId2(String name, String idCard, ThirdConf config) throws Exception {
        try{
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            Credential  crd = new Credential(config.getSecretId(),config.getSecretKey());

            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile hpf = new HttpProfile();
            hpf.setEndpoint(config.getEndPoint());

            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(hpf);
            // 实例化要请求产品的client对象,clientProfile是可选的
            FaceidClient client = new FaceidClient(crd, config.getRegion(), clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            IdCardVerificationRequest req = new IdCardVerificationRequest();

            req.setName(name);
            req.setIdCard(idCard);
            // 返回的resp是一个IDCardOCRResponse的实例，与请求对象对应
            IdCardVerificationResponse  resp = client.IdCardVerification(req);
            log.info("身份证二要素识姓名:["+name+"],idcard["+idCard+"]别返回结果: "+ AbstractModel.toJsonString(resp));
            if("0".equals(resp.getResult())){
                return true;
            }else{
                throw new BaseException(resp.getDescription());
            }
        }catch(TencentCloudSDKException e){
            log.error("身份证二要素认证出错:姓名:{},身份证号{},错误信息{}",name,idCard,e.getMessage());
            throw new BaseException(e.getMessage()) ;
        }catch (Exception e){
            log.error("身份证二要素认证出错:姓名:{},身份证号{},错误信息{}",name,idCard,e.getMessage());
            throw e;
        }
    }

    @Override
    public boolean bankCard4(String bankCard, String name, String phone, String idCard, ThirdConf conf) throws Exception {
        try{
            // 实例化一个认证对象，入参需要传入腾讯云账户 SecretId 和 SecretKey，此处还需注意密钥对的保密
            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露，并威胁账号下所有资源的安全性。以下代码示例仅供参考，建议采用更安全的方式来使用密钥，请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            Credential cred = new Credential(conf.getSecretId(), conf.getSecretKey());
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            // 推荐使用北极星，相关指引可访问如下链接
            // https://git.woa.com/tencentcloud-internal/tencentcloud-sdk-java#%E5%8C%97%E6%9E%81%E6%98%9F
            httpProfile.setEndpoint(conf.getEndPoint());
            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            FaceidClient client = new FaceidClient(cred, conf.getRegion(), clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象

            if(StringUtils.isNotEmpty(phone)){
                BankCard4EVerificationRequest req = new BankCard4EVerificationRequest();
                req.setName(name);
                req.setBankCard(bankCard);
                req.setIdCard(idCard);
                req.setPhone(phone);
                // 返回的resp是一个BankCard4EVerificationResponse的实例，与请求对象对应
                BankCard4EVerificationResponse resp = client.BankCard4EVerification(req);
                log.info("银行卡四要素:["+bankCard+","+name+","+phone+","+idCard+"]返回结果: "+ AbstractModel.toJsonString(resp));

                if("0".equals(resp.getResult())){
                    return true;
                }else{
                    throw new BaseException(resp.getDescription());
                }
            }else{
                BankCardVerificationRequest req = new BankCardVerificationRequest();
                req.setIdCard(idCard);
                req.setName(name);
                req.setBankCard(bankCard);
                BankCardVerificationResponse resp = client.BankCardVerification(req);
                log.info("银行卡三要素:["+bankCard+","+name+","+phone+","+idCard+"]返回结果: "+ AbstractModel.toJsonString(resp));
                if("0".equals(resp.getResult())){
                    return true;
                }else{
                    throw new BaseException(resp.getDescription());
                }
            }
        } catch (TencentCloudSDKException e) {
            log.error("银行卡三/四要素认证出错:手机号:{},姓名{},身份证{},银行卡{},状态码{},错误信息{}",phone,name,idCard,bankCard,e.getErrorCode(),e.getMessage());
            throw  e;
        } catch(Exception e){
            e.printStackTrace();
            log.error("银行卡三/四要素认证出错:手机号:{},姓名{},身份证{},银行卡{},错误信息{}",phone,name,idCard,bankCard,e.getMessage());
            throw e;
        }
    }



    @Override
    public boolean bankCard3(String bankCard, String name, String idCard, ThirdConf conf) throws Exception {
        return this.bankCard4(bankCard,name,null,idCard,conf);
    }


    public  ThirdConf  getThirdConfig(String code,String type ){

        Map configMap = this.mpOtherThirdConfig(code);
        if(configMap == null){
            throw new RuntimeException("站点第三方参数未配置!");
        }
        Map subMap = (Map) configMap.get(type);
        ThirdConf thirdConf = JsonUtils.parseObject(JsonUtils.toJsonString(subMap),ThirdConf.class);
        return thirdConf;
    }

    public Map mpOtherThirdConfig(String domainCode) {


        RemoteSysUnitDomainVo unitDomainVo = this.remoteConfigService.queryByDomainName(domainCode);

        if(unitDomainVo == null){
            this.invalidationParamsException("此站点无配置-身份证识别等");
        }
        String thirdConfigStr = unitDomainVo.getWeChatThirdParams();
        return JsonUtils.parseObject(thirdConfigStr,Map.class);
//        String cacheKey = MpContants.MP_DOMAIN_KEY+domainCode;
//        Object obj = RedisUtils.getCacheObject(cacheKey);
//        Map map = JsonUtils.parseObject(JsonUtils.toJsonString(obj),Map.class);
//        SysUnitDomain mpDomainVo =  RedisUtils.getCacheObject(cacheKey);
//        if(mpDomainVo != null){
//            String thirdConfigStr = mpDomainVo.getWeChatThirdParams();
//            return JsonUtils.parseObject(thirdConfigStr,Map.class);
//        }
//        return null;

    }
}
