package com.hzya.frame.bip.v3.v2207.service.impl;


import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.google.gson.Gson;
import com.hzya.frame.base.PluginBaseEntity;
import com.hzya.frame.basedao.service.impl.BaseService;
import com.hzya.frame.bip.v3.v2207.dao.IBipOrgsDao;
import com.hzya.frame.bip.v3.v2207.dao.IBipOrgsDetailsDao;
import com.hzya.frame.bip.v3.v2207.dao.IBipSupplierDao;
import com.hzya.frame.bip.v3.v2207.dao.IBipSupplierDetailsDao;
import com.hzya.frame.bip.v3.v2207.entity.BipOrgsDetailsEntity;
import com.hzya.frame.bip.v3.v2207.entity.BipOrgsEntity;
import com.hzya.frame.bip.v3.v2207.entity.BipSupplierDetailsEntity;
import com.hzya.frame.bip.v3.v2207.entity.BipSupplierEntity;
import com.hzya.frame.bip.v3.v2207.service.IBipV32207Service;
import com.hzya.frame.dateutil.DateUtil;
import com.hzya.frame.util.PluginUtils;
import com.hzya.frame.util.bipV3.Encryption;
import com.hzya.frame.util.bipV3.SHA256Util;
import com.hzya.frame.util.oldNcc.CompressUtil;
import com.hzya.frame.util.oldNcc.Decryption;
import com.hzya.frame.web.entity.BaseResult;
import com.hzya.frame.web.entity.JsonResultEntity;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import java.net.URLEncoder;
import java.util.*;


@Service(value = "bipV32207Service")
public class BipV32207ServiceImpl extends BaseService<BipSupplierEntity, String> implements IBipV32207Service {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    //定义项目开始同步日期
    private String ts = "2023-09-30 15:47:08";
    //组织的同步日期
    private String orgsts = "2023-09-30 15:47:08";
    @Autowired
    private IBipSupplierDao bipSupplierDao;

    @Autowired
    private IBipSupplierDetailsDao bipSupplierDetailsDao;

    @Autowired
    private IBipOrgsDao bipOrgsDao;

    @Autowired
    private IBipOrgsDetailsDao bipOrgsDetailsDao;


    /**
     * @param object
     * @return com.hzya.frame.web.entity.JsonResultEntity
     * @Description 获取token
     **/
    @Override
    public JsonResultEntity thirdInterfaceGetToken(JSONObject object) {
        JSONObject jsonObject = getstrObj("jsonStr", object);
        String client_id = jsonObject.getString("client_id");
        String pubKey = jsonObject.getString("pubKey");
        String client_secret = jsonObject.getString("client_secret");
        String username = jsonObject.getString("username");
        String pwd = jsonObject.getString("pwd");
        String busi_center = jsonObject.getString("busi_center");
        String dsname = jsonObject.getString("dsname");
        String baseUrl = jsonObject.getString("baseUrl");
        Map<String, String> paramMap = new HashMap<String, String>();
        // 密码模式认证
        paramMap.put("grant_type", "password");
        // 第三方应用id
        paramMap.put("client_id", client_id);
        // 第三方应用secret 公钥加密
        try {
            paramMap.put("client_secret", URLEncoder.encode(Encryption.pubEncrypt(pubKey, client_secret), "utf-8"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        // ncc用户名
        paramMap.put("username", username);
        // 密码 公钥加密
        try {
            paramMap.put("password", URLEncoder.encode(Encryption.pubEncrypt(pubKey, pwd), "utf-8"));
        } catch (Exception e) {
            return BaseResult.getFailureMessageEntity("获取token失败");
        }
        // 账套编码
        paramMap.put("biz_center", busi_center);
        // 签名
        String sign = SHA256Util.getSHA256(client_id + client_secret + username + pwd + pubKey, pubKey);
        paramMap.put("signature", sign);
        paramMap.put("dsname", dsname);
        String url = baseUrl + "/nccloud/opm/accesstoken";
        String mediaType = "application/x-www-form-urlencoded";
        String token = null;
        try {
            token = doPostHutool(url, paramMap, mediaType, null, "", "token");
        } catch (Exception e) {
            return BaseResult.getFailureMessageEntity("获取token失败");
        }
        if (JSONUtil.isTypeJSON(token)) {
            JSONObject jsonObject1 = JSONObject.parseObject(token);
            return BaseResult.getSuccessMessageEntity("获取token成功", jsonObject1);
        } else {
            return BaseResult.getSuccessMessageEntity("获取token成功", token);
        }
    }

    /**
     * 发送post请求
     *
     * @param baseUrl
     * @param paramMap
     * @param mediaType
     * @param headers
     * @param json
     * @return
     */
    private String doPostHutool(String baseUrl, Map<String, String> paramMap, String mediaType, Map<String, String> headers, String json, String type) {
        String result = null;

        try {
            StringBuffer sb = new StringBuffer();
            sb.append(baseUrl);
            if (paramMap != null) {
                sb.append("?");
                for (Map.Entry<String, String> entry : paramMap.entrySet()) {
                    String key = entry.getKey();
                    String value = entry.getValue();
                    sb.append(key + "=" + value).append("&");
                }
            }
            if ("bill".equals(type)) {
                sb.append("?");
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    String key = entry.getKey();
                    String value = entry.getValue();
                    sb.append(key + "=" + value).append("&");
                }
            }
            baseUrl = sb.toString().substring(0, sb.toString().length() - 1);
            HttpRequest re = HttpRequest.post(baseUrl);
            re.addHeaders(headers);
            result = re.body(json)
                    .timeout(2000000)//超时，毫秒
                    .execute().body();

        } catch (Exception e) {
            e.printStackTrace();
        }


        return result;
    }

    /**
     * @param key
     * @param object
     * @return com.alibaba.fastjson.JSONObject
     * @Author lvleigang
     * @Description 获取对象转换成jsonobj
     * @Date 11:51 下午 2023/7/10
     **/
    public JSONObject getstrObj(String key, JSONObject object) {
        if (checkStr(object.getString(key))) {
            return object.getJSONObject(key);
        }
        return new JSONObject();
    }

    /**
     * @param str
     * @return void
     * @Author lvleigang
     * @Description 校验字符串
     * @Date 11:41 上午 2022/12/7
     **/
    protected Boolean checkStr(String str) {
        Boolean flag = true;
        if (str == null || "".equals(str)) {
            flag = false;
        }
        return flag;
    }

    /**
     * @param jsonObject
     * @return com.hzya.frame.web.entity.JsonResultEntity
     * @Description 获取供应商
     **/
    @Override
    public JsonResultEntity thirdInterfaceGetSupplier(JSONObject jsonObject) {
        BipSupplierEntity bipSupplierEntity = getData("jsonStr", jsonObject, BipSupplierEntity.class);
        //设置查询区间
        bipSupplierEntity.setTs(ts);
        logger.info("查询供应商数据，当前TS："+ts);
        List<BipSupplierEntity> bipSupplierEntities = bipSupplierDao.thirdInterfaceGetSupplier(bipSupplierEntity);
        //更新TS时间
        ts = DateUtil.dateToString(new Date(),"yyyy-MM-dd HH:mm:ss");
        logger.info("TS已更新："+ts);
        //System.out.println("查询供应商明细");
        logger.info("查询供应商明细"+JSON.toJSONString(bipSupplierEntities));
        List<JSONObject> jsonObjectList=new ArrayList<>();
        //[{"code":"SL20231101727","dataSourceCode":"master","name":"无锡恒君安管理咨询有限公司","taxpayerid":"91320205MAD2HAQN6Q","tripartiteId":"0001A31000000002M3TS","ts":"2023-11-16 14:05:10"}]

        List<BipSupplierDetailsEntity>  bipSupplierDetails = null;
        for (BipSupplierEntity supplierEntity : bipSupplierEntities) {
            List<JSONObject> list=new ArrayList<>();
            JSONObject jsonObjectResult=new JSONObject();
            jsonObjectResult.put("code",supplierEntity.getCode());
            jsonObjectResult.put("name",supplierEntity.getName());
            jsonObjectResult.put("taxpayerid",supplierEntity.getTaxpayerid());
            jsonObjectResult.put("def1",supplierEntity.getDef1());
            jsonObjectResult.put("def2",supplierEntity.getDef2());
            jsonObjectResult.put("def3",supplierEntity.getDef3());
            jsonObjectResult.put("tripartiteId",supplierEntity.getTripartiteId());
            //根据供应商编码和名称查询明细
            String code = supplierEntity.getCode();
            String name = supplierEntity.getName();
            //System.out.println("根据供应处名称，编码获取明细数据：code:"+code +"name:"+name);
            logger.info("根据供应处名称，编码获取明细数据：code:"+code +"name:"+name);
            BipSupplierDetailsEntity bipSupplierDetailsEntity = new BipSupplierDetailsEntity();
            bipSupplierDetailsEntity.setCode(code);
            bipSupplierDetailsEntity.setName(name);
            logger.info("根据供应商编码，名称查询银行档案 {}",JSON.toJSONString(bipSupplierDetailsEntity));
            List<BipSupplierDetailsEntity> bipSupplierDetailsEntities =    queryBipSupplierDetails(bipSupplierDetailsEntity) ;
//                    /bipSupplierDetails.stream().filter(that-> code.equalsIgnoreCase(that.getCode() ) &&   name.equalsIgnoreCase(that.getName() ) ).collect(Collectors.toList());
            logger.info("根据供应处名称，编码获取明细数据 bipSupplierDetailsEntities值：{}",JSON.toJSONString(bipSupplierDetailsEntities));
          if (bipSupplierDetailsEntities.size()>0 && null!=bipSupplierDetailsEntities){
                bipSupplierDetailsEntities.get(0).setIsdefault("-8073674727882144390");
                for (BipSupplierDetailsEntity supplierDetailsEntity : bipSupplierDetailsEntities) {
                    JSONObject jsonObjectDetails=new JSONObject();
                    jsonObjectDetails.put("splitbank",supplierDetailsEntity.getSplitbank());
                    jsonObjectDetails.put("bankaccno",supplierDetailsEntity.getBankaccno());
                    jsonObjectDetails.put("combinno",supplierDetailsEntity.getCombinno());
                    jsonObjectDetails.put("isdefault",supplierDetailsEntity.getIsdefault());
                    list.add(jsonObjectDetails);
                }
            }
             jsonObjectResult.put("details",list);
            jsonObjectList.add(jsonObjectResult);
        }
        return BaseResult.getSuccessMessageEntity("查询成功",jsonObjectList);
    }
    @DS("oracle91")
    private  List<BipSupplierDetailsEntity>  queryBipSupplierDetails(BipSupplierDetailsEntity bipSupplierDetailsEntity){
//        BipSupplierDetailsEntity bipSupplierDetailsEntity=new BipSupplierDetailsEntity();
//        bipSupplierDetailsEntity.setCode(supplierEntity.getCode());
//        bipSupplierDetailsEntity.setName(supplierEntity.getName());

        List<BipSupplierDetailsEntity> bipSupplierDetailsEntities = bipSupplierDetailsDao.thirdInterfaceGetSupplierDetails(bipSupplierDetailsEntity);
        return bipSupplierDetailsEntities;
    }


    /**
     * 获取BIP组织数据
     * @param jsonObject
     * @return
     */
    @Override
    public JsonResultEntity thirdInterfaceGetOrgs(JSONObject jsonObject) {
        BipOrgsEntity bipOrgsEntity = getData("jsonStr", jsonObject, BipOrgsEntity.class);
        //设置查询区间
        bipOrgsEntity.setOrgsts(orgsts);
        logger.info("查询组织数据，当前TS：" + orgsts);
        List<BipOrgsEntity> bipOrgsEntities = bipOrgsDao.thirdInterfaceGetOrgs(bipOrgsEntity);
        //更新TS时间
        orgsts = DateUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss");
        logger.info("组织TS已更新：" + orgsts);
        logger.info("查询组织明细" + JSON.toJSONString(bipOrgsEntities));
        List<JSONObject> jsonObjectList = new ArrayList<>();
        if (null != bipOrgsEntities && bipOrgsEntities.size() > 0) {
            for (BipOrgsEntity orgsEntity : bipOrgsEntities) {
                List<JSONObject> list = new ArrayList<>();
                JSONObject jsonObjectResult = new JSONObject();
                jsonObjectResult.put("code", orgsEntity.getCode());//单位编码
                jsonObjectResult.put("name", orgsEntity.getName());//单位名称
                jsonObjectResult.put("tripartiteId", orgsEntity.getTripartiteId());//BIPID
                //根据组织主键查询明细
                String tripartiteId = orgsEntity.getTripartiteId();
                //System.out.println("根据供应处名称，编码获取明细数据：code:"+code +"name:"+name);
                logger.info("根据组织主键获取明细数据：pk_financeorg:{}", tripartiteId);
                BipOrgsDetailsEntity bipOrgsDetailsEntity = new BipOrgsDetailsEntity();
                bipOrgsDetailsEntity.setControlorg(tripartiteId);
                List<BipOrgsDetailsEntity> bipOrgsDetailsEntities = queryBipOrgsDetails(bipOrgsDetailsEntity);
                if (bipOrgsDetailsEntities.size() > 0 && null != bipOrgsDetailsEntities) {
                    for (BipOrgsDetailsEntity orgsDetailsEntity : bipOrgsDetailsEntities) {
                        JSONObject jsonObjectDetails = new JSONObject();
                        jsonObjectDetails.put("bankCode", orgsDetailsEntity.getBankCode());//开户行编码
                        jsonObjectDetails.put("bankName", orgsDetailsEntity.getBankName());//开户行名称
                        jsonObjectDetails.put("accnum", orgsDetailsEntity.getAccnum());//账户
                        jsonObjectDetails.put("cnapsCode", orgsDetailsEntity.getCnapsCode());//联行号
                        list.add(jsonObjectDetails);
                    }
                }
                jsonObjectResult.put("details", list);
                jsonObjectList.add(jsonObjectResult);
            }
        }
        return BaseResult.getSuccessMessageEntity("查询成功", jsonObjectList);
    }
    private  List<BipOrgsDetailsEntity>  queryBipOrgsDetails(BipOrgsDetailsEntity bipOrgsDetailsEntity){
        List<BipOrgsDetailsEntity> bipOrgsDetailsEntities = bipOrgsDetailsDao.thirdInterfaceGetOrgsDetails(bipOrgsDetailsEntity);
        return bipOrgsDetailsEntities;
    }

    /**
     * @param object
     * @return com.hzya.frame.web.entity.JsonResultEntity
     * @Description 新增供应商
     **/
    @Override
    public JsonResultEntity thirdInterfaceSaveSupplier(JSONObject object) {
        JSONObject jsonObject = getstrObj("jsonStr", object);
        //认证access_token
        String access_token = jsonObject.getString("access_token");
        //认证security_key
        String security_key = jsonObject.getString("security_key");
        //服务器ip：port
        String baseUrl = jsonObject.getString("baseUrl");
        //api方法
        String apiUrl = jsonObject.getString("apiUrl");
        //发送的数据
        String sendData =jsonObject.getString("sendData");
        //对应于在第三方应用注册当中的app_id
        String client_id = jsonObject.getString("client_id");
        //公钥
        String pubKey = jsonObject.getString("pubKey");
        //接口调用业务标识
        String busi_id = jsonObject.getString("busi_id");
        //重复调用检查
        String repeat_check = jsonObject.getString("repeat_check");
        //返回值压缩加密级别
        String secret_level = jsonObject.getString("secret_level") == null ? "L0": jsonObject.getString("secret_level") ;
        try {
            String returnStr = sendApi(access_token, security_key, baseUrl,apiUrl,sendData,client_id,pubKey,busi_id,repeat_check,secret_level);
            if(JSONUtil.isTypeJSON(returnStr)){
                JSONObject jsonObject1 = JSONObject.parseObject(returnStr);
                return BaseResult.getSuccessMessageEntity("发送数据成功",jsonObject1);
            }else {
                return BaseResult.getSuccessMessageEntity("发送数据成功",returnStr);
            }
        } catch (Exception e) {
            return BaseResult.getFailureMessageEntity("发送数据错误");
        }
    }

    /**
     * 供应商传递OA
     * @param jsonObject
     * @return
     */
    @Override
    public JsonResultEntity thirdInterfaceSendOa(JSONObject jsonObject) throws Exception {
        JSONObject jsonObjectStr = getstrObj("jsonStr", jsonObject);
        PluginBaseEntity pluginBaseEntity = PluginUtils.getPluginsById(jsonObjectStr.getString("plug_id"));
        JsonResultEntity s = pluginBaseEntity.executeBusiness(jsonObjectStr);
        return BaseResult.getSuccessMessageEntity("传递成功");
    }


    /**
     * @param access_token 认证access_token
     * @param security_key 认证security_key
     * @param baseUrl      服务器ip：port
     * @param apiUrl       api方法
     * @param putParameter 发送的数据
     * @param client_id    对应于在第三方应用注册当中的app_id
     * @param pubKey       公钥
     * @param busi_id      接口调用业务标识
     * @param repeat_check 重复调用检查
     * @param secret_level 返回值压缩加密级别
     * @return java.lang.String
     * @Author lvleigang
     * @Description 发起api接口
     * @Date 9:52 上午 2023/8/22
     **/
    private String sendApi(String access_token, String security_key, String baseUrl, String apiUrl, String putParameter, String client_id, String pubKey, String busi_id, String repeat_check, String secret_level) throws Exception{
        // header 参数
        Map<String, String> headermap = new HashMap<>();
        headermap.put("access_token", access_token);
        headermap.put("client_id", client_id);
        StringBuffer sb = new StringBuffer();
        sb.append(client_id);
        if (StringUtils.isNotBlank(putParameter)) {
            sb.append(putParameter);
        }
        sb.append(pubKey);
        String sign = SHA256Util.getSHA256(sb.toString(), pubKey);
        headermap.put("signature", sign);
        if (StringUtils.isNotBlank(busi_id)) {
            headermap.put("busi_id", busi_id);
        }
        if (StringUtils.isNotBlank(repeat_check)) {
            headermap.put("repeat_check", repeat_check);
        }
        String mediaType = "application/json;charset=utf-8";
        // 表体数据json
        // 根据安全级别选择加密或压缩请求表体参数
        String json = dealRequestBody(putParameter, security_key, secret_level);
        // 返回值
        String sendUrl = baseUrl + apiUrl;
        String result = doPostHutool(sendUrl, null, mediaType, headermap, json, "bill");
        String changeData = dealResponseBody(result, security_key, secret_level);
        return changeData;
    }

    // 返回值进行过加密和压缩，对返回值进行解压和解密
    private static String dealResponseBody(String source, String security_key, String level) throws Exception {
        String result = null;
        if (org.apache.commons.lang3.StringUtils.isEmpty(level) || SecretConst.LEVEL0.equals(level)) {
            result = source;
        } else if (SecretConst.LEVEL1.equals(level)) {
            result = Decryption.symDecrypt(security_key, source);
        } else if (SecretConst.LEVEL2.equals(level)) {
            result = CompressUtil.gzipDecompress(source);
        } else if (SecretConst.LEVEL3.equals(level)) {
            result = CompressUtil.gzipDecompress(Decryption.symDecrypt(security_key, source));
        } else if (SecretConst.LEVEL4.equals(level)) {
            result = Decryption.symDecrypt(security_key, CompressUtil.gzipDecompress(source));
        } else {
            throw new Exception("无效的安全等级");
        }

        return result;
    }

    // 根据安全级别设置，表体是否加密或压缩
    private static String dealRequestBody(String source, String security_key, String level) throws Exception {
        String result = null;
        if (org.apache.commons.lang3.StringUtils.isEmpty(level) || SecretConst.LEVEL0.equals(level)) {
            result = source;
        } else if (SecretConst.LEVEL1.equals(level)) {
            result = Encryption.symEncrypt(security_key, source);
        } else if (SecretConst.LEVEL2.equals(level)) {
            result = CompressUtil.gzipCompress(source);
        } else if (SecretConst.LEVEL3.equals(level)) {
            result = Encryption.symEncrypt(security_key, CompressUtil.gzipCompress(source));
        } else if (SecretConst.LEVEL4.equals(level)) {
            result = CompressUtil.gzipCompress(Encryption.symEncrypt(security_key, source));
        } else {
            throw new Exception("无效的安全等级");
        }

        return result;
    }

    class SecretConst {
        /**
         * LEVEL0 不压缩、不加密
         */
        public static final String LEVEL0 = "L0";
        /**
         * LEVEL1 只加密、不压缩
         */
        public static final String LEVEL1 = "L1";
        /**
         * LEVEL2 只压缩、不加密
         */
        public static final String LEVEL2 = "L2";
        /**
         * LEVEL3 先压缩、后加密
         */
        public static final String LEVEL3 = "L3";
        /**
         * LEVEL4 先加密、后压缩
         */
        public static final String LEVEL4 = "L4";
    }
}
