package com.seeyon.apps.src_hxinvoice.service.impl;

import cn.hutool.log.Log;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.seeyon.apps.common.config.ICstConfigApi;
import com.seeyon.apps.common.plugin.vo.ConfigVo;
import com.seeyon.apps.src_hxinvoice.constants.HxinvoiceConstants;
import com.seeyon.apps.src_hxinvoice.dao.IHxinvoiceDao;
import com.seeyon.apps.src_hxinvoice.service.IInvoiceService;
import com.seeyon.apps.src_hxinvoice.util.*;
import com.seeyon.apps.src_powerfeeinvoice.service.PowerFeeService;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.SystemEnvironment;
import com.seeyon.ctp.common.ctpenumnew.manager.EnumManager;
import com.seeyon.ctp.common.po.filemanager.Attachment;
import com.seeyon.ctp.organization.bo.V3xOrgAccount;
import com.seeyon.ctp.organization.bo.V3xOrgMember;
import com.seeyon.ctp.organization.manager.OrgManager;
import com.seeyon.ctp.util.StringUtil;
import com.seeyon.ctp.util.UUIDLong;
import com.seeyon.v3x.services.form.FormFactory;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 配置web.xml完成回调函数
 */
public class InvoiceServiceImpl implements IInvoiceService {

    protected ICstConfigApi cstConfigApi = (ICstConfigApi) AppContext.getBean("cstConfigApi");
    private static Log log = Log.get(InvoiceServiceImpl.class);
    private FormFactory formFactory;
    public FormFactory getFormFactory() {
        if (formFactory == null) {formFactory = (FormFactory) AppContext.getBean("formFactory");}return formFactory;
    }

    public ConfigVo getHxinvoiceConfig() {return cstConfigApi.getConfig(getPluginId());}

    public String getPluginId() {return HxinvoiceConstants.getPluginId();}

    private IHxinvoiceDao hxinvoiceDao;
    public void setHxinvoiceDao(IHxinvoiceDao hxinvoiceDao) {this.hxinvoiceDao = hxinvoiceDao;}
    public IHxinvoiceDao getHxinvoiceDao() {
        if (this.hxinvoiceDao == null) {this.hxinvoiceDao = ((IHxinvoiceDao)AppContext.getBean("hxinvoiceDao"));}return hxinvoiceDao;
    }

    private EnumManager enumManagerNew;
    public void setEnumManagerNew(EnumManager enumManagerNew) {this.enumManagerNew = enumManagerNew; }
    public EnumManager getEnumManagerNew() {
        if (enumManagerNew == null) {enumManagerNew = (EnumManager) AppContext.getBean("enumManagerNew");}return enumManagerNew;
    }

    private OrgManager orgManager;
    public void setOrgManager(OrgManager orgManager) {this.orgManager = orgManager; }
    public OrgManager getOrgManager() {
        if (orgManager == null) {orgManager = (OrgManager) AppContext.getBean("orgManager");}return orgManager;
    }

    private void handlePowerFeeCallBack(String DDQQLSH,JSONObject DDFPXX,JSONArray FILEITEMLISTS,String orderState,String invoiceItemDesc,Long memberId,Long account) throws Exception {
        //发票号码
        //发票代码
        //实际开票日期
        //订单状态
        //订单状态描述
        //数电发票附件
        //查询档案
        String path = SystemEnvironment.getApplicationFolder();
        //处理水电费开票信息回写
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String FPDM = DDFPXX.getString("FPDM");//发票代码
        String FPHM = DDFPXX.getString("FPHM");//发票号码
        String KPRQ = null;
        try {
            KPRQ = df.format(df.parse(DDFPXX.getString("KPRQ")));
        }catch (Exception e) {
            e.printStackTrace();
        }
        String DDH = DDFPXX.getString("DDH");//订单号
        Map<String,Object> map = new HashMap<>();
        map.put("发票代码",FPDM);
        map.put("发票号码",FPHM);
        map.put("实际开票日期",KPRQ);
        map.put("订单状态",orderState);
        map.put("订单请求流水号",DDQQLSH);
        map.put("订单请求批次号",DDH);
        map.put("订单状态描述",invoiceItemDesc);
        map.put("订单号",DDH);
        map.put("发票类型代码",DDFPXX.getString("FPLXDM"));
        map.put("购买方信息",DDFPXX.getString("GMFMC"));//购买方名称
        map.put("购买方税号",DDFPXX.getString("GMFSBH")); //购买方税号
        map.put("购买方编号","");
        map.put("销售方纳税人识别号",DDFPXX.getString("XHFSBH"));
        map.put("销售方编号","");
        map.put("销售方名称",DDFPXX.getString("XHFMC"));
        map.put("开票日期",KPRQ);
        map.put("开票人",DDFPXX.getString("KPR"));
        map.put("购买方联系方式",DDFPXX.getString("GMFDH"));
        map.put("开票类型",DDFPXX.getString("KPLX"));
        map.put("系统来源","");
        map.put("本次开票金额",DDFPXX.getString("JSHJ"));
        map.put("电子税票系统返回结果",invoiceItemDesc);
        //附件处理
        List<String> fileNames = new ArrayList<String>();
        saveAttachments(fileNames,FILEITEMLISTS,path,DDQQLSH,DDFPXX,KPRQ,FPHM);
        PowerFeeService powerFeeService = new PowerFeeService();
        powerFeeService.updatePowerFeeForm(map);
        powerFeeService.insertIntoInvoiceForm(map,fileNames,memberId,account);
    }

    private void saveAttachments(List<String> fileNames,JSONArray FILEITEMLISTS,String path,String DDQQLSH,JSONObject DDFPXX,String KPRQ,String FPHM) {
        FileUtil fileUtil = new FileUtil();
        for(int n = 0 ; n < FILEITEMLISTS.size() ; n++){
            JSONObject FILEITEMLIST = FILEITEMLISTS.getJSONObject(n);
//          获取后缀
            String WJLX = FILEITEMLIST.getString("WJLX");
            String FILECONTENT = FILEITEMLIST.getString("FILECONTENT");
//          bese64解密
            byte[] fileBytes = Base64.decodeBase64(FILECONTENT);
            try {
//              判断文件路径是否存在
                fileUtil.isFilePath(path+"/invoiceDate/"+DDQQLSH);
                String GMFMC = DDFPXX.getString("GMFMC");
                String newKPRQStr = KPRQ.replace("-", "").replace(" ", "").replace(":", "");
                String fileInvoiceName = "dzfp_"+FPHM+"_"+GMFMC+"_"+newKPRQStr;
                String fileName = path+"/invoiceDate/"+DDQQLSH+"/"+fileInvoiceName+"."+WJLX;
                FileOutputStream fos = new FileOutputStream(fileName);
                int bufferSize = 1024; // 每次写入的块大小为1KB
                for (int t = 0; t < fileBytes.length; t += bufferSize) {
                    int length = Math.min(bufferSize, fileBytes.length - t);
                    fos.write(fileBytes, t, length);
                }
                fos.close();
                fileNames.add(fileName);
            } catch (IOException e) {
                System.out.println("保存文件时出错：" + e.getMessage());
            }
        }
    }

    @Override
    public JSONObject pushOrderInfoAndInvoiceInfoService(Map<String,Object> param) throws Exception {
        ConfigVo configVo = getHxinvoiceConfig();
//        获取产品标准地址
        String path = SystemEnvironment.getApplicationFolder();
        FileUtil fileUtil = new FileUtil();
//        FormExportUtil formExportUtil = new FormExportUtil();
//        JSONObject res = new JSONObject();
//        获取附件上传接口人员登录信息
        String uploadMemberLoginName = configVo.getParamVal(HxinvoiceConstants.uploadMemberLoginName.name());
//        根据人员登录名获取人员对象信息
        V3xOrgMember v3xOrgMember = orgManager.getMemberByLoginName(uploadMemberLoginName);
//        获取附件上传单位名称
        String updateAccountName = configVo.getParamVal(HxinvoiceConstants.updateAccountName.name());
//        根据单位名称获取单位对象信息
        V3xOrgAccount v3xOrgAccount = orgManager.getAccountByName(updateAccountName);
//            		secretKey，解析回调参数中的信息
        String secretKey = configVo.getParamVal(HxinvoiceConstants.secretKey.name());
        String password = secretKey.substring(0,24);
        GzipUtils gzipUtils = new GzipUtils();
        TripleDesUtil tripleDesUtil = new TripleDesUtil();
        String stateEnumId = configVo.getParamVal(HxinvoiceConstants.stateEnumId.name());
        Map<String,String> stateEnum = hxinvoiceDao.getCtpEnumItemsByEnumId(stateEnumId);
        String con = param.get("content").toString();
//        System.out.println(con);
//        System.out.println("");
        byte[] decodedBytes = Base64.decodeBase64(con);
//        判断是否压缩
        String iszipCode = param.get("zipCode") == null ? "0" : param.get("zipCode").toString();
        byte[] dec = decodedBytes;
        if("1".equals(iszipCode)){
            dec = gzipUtils.decompress(decodedBytes);
        }
//        判断是否加密
        byte[] d= dec;
        String isencryptCode = param.get("encryptCode").toString();
        if("1".equals(isencryptCode)){
            d = tripleDesUtil.decryptMode(password,dec);
        }
//        编码转译
        String str = new String(d,"UTF-8");
        String s = "{'param':"+str+"}";
//        JSONArray jso = JSONArray.parseObject(str);
        JSONObject js = JSONObject.parseObject(s);
        JSONArray jsonArray = js.getJSONArray("param");
        JSONArray jsonres = new JSONArray();
        for(int i = 0 ; i < jsonArray.size() ; i++){
            JSONObject jsonObject = jsonArray.getJSONObject(i);
//          获取发票号码、发票代码、实际开票日期、订单状态、凭证类型、数电票二维码
            JSONObject DDFPXX = jsonObject.getJSONObject("DDFPXX");
            String DDQQLSH = DDFPXX.getString("DDQQLSH");
            Map<String ,String> map = new HashMap<>();
            String FPDM = DDFPXX.getString("FPDM");//发票代码
            String FPHM = DDFPXX.getString("FPHM");//发票号码
            String KPRQ = DDFPXX.getString("KPRQ");//开票日期
//                String SDEWMURL = DDFPXX.getString("SDEWMURL");//数电二维码交付地址
            String DDZT = DDFPXX.getString("DDZT");//订单状态
            String DDZTXX = DDFPXX.getString("DDZTXX");//订单状态描述
            String DDH = DDFPXX.getString("DDH");//订单号
            String JSHJ = DDFPXX.getString("JSHJ");//主表价税合计
            String HJJE = DDFPXX.getString("HJJE");//主表合计金额
            String HJSE = DDFPXX.getString("HJSE");//主表合计税额

            log.info("回调函数关键字段回写：发票代码："+FPDM+"发票号码"+FPHM+"开票日期"+KPRQ+"订单状态"+DDZT+"订单状态描述"+DDZTXX);

            JSONArray FILEITEMLISTS = jsonObject.getJSONArray("FILEITEMLIST");

            map.put("发票代码",FPDM);
            map.put("合计金额",JSHJ);
            map.put("合计税额",HJSE);
            map.put("发票号码",FPHM);
            map.put("订单状态描述",DDZTXX);
            map.put("实际开票日期",KPRQ);
            map.put("订单号",DDH);
            switch(DDZT){
                case "030000":
                    map.put("订单状态",stateEnum.get("订单开票成功"));
                    map.put("开票事项说明","开票成功："+DDZTXX);
                    break;
                case "031000":
                    map.put("订单状态",stateEnum.get("订单未开票"));
                    map.put("开票事项说明","未开票："+DDZTXX);
                    break;
                case "031999":
                    map.put("订单状态",stateEnum.get("订单开票失败"));
                    map.put("开票事项说明","订单开票失败："+DDZTXX);
                    break;
                case "032000":
                    map.put("订单状态",stateEnum.get("订单开票中"));
                    map.put("开票事项说明","开票中："+DDZTXX);
                    break;
                case "032999":
                    map.put("订单状态",stateEnum.get("订单无效"));
                    map.put("开票事项说明","无效："+DDZTXX);
                    break;
            }
            map.put("电子税票系统返回结果",DDZTXX);
            String XHFSBH = DDFPXX.getString("XHFSBH");
            JSONArray DDMXXXS = jsonObject.getJSONArray("DDMXXX");
            if(DDQQLSH.startsWith("ZNDBLSH")){
                //处理电费开票数据回写
                JSONObject json = new JSONObject();
                json.put("DDQQLSH",DDQQLSH);
                json.put("NSRSBH",XHFSBH);
                try {
                    handlePowerFeeCallBack(DDQQLSH,DDFPXX,FILEITEMLISTS,map.get("订单状态"),map.get("开票事项说明"),v3xOrgMember.getId(),v3xOrgAccount.getId());
                    json.put("ZTDM","000000");
                    json.put("ZTXX","接收成功");
                    jsonres.add(json);
                }catch (Exception e) {
                    log.error(e);
                    json.put("ZTDM","009999");
                    json.put("ZTXX","接收失败");
                    jsonres.add(json);
                }
            }else {
                String formId = hxinvoiceDao.getInvoiceIdByCode(DDQQLSH,XHFSBH);
                System.out.println(DDQQLSH+":"+XHFSBH+"查询到的主表ID为"+formId);
                if(!"0".equals(formId)){
                    log.info("对应MAP数据："+map.toString());

                    List<String> fileNames = new ArrayList<>();
                    saveAttachments(fileNames,FILEITEMLISTS,path,DDQQLSH,DDFPXX,KPRQ,FPHM);
                    List<Attachment> attachments = fileUtil.fileUpload(fileNames,formId,v3xOrgMember.getId(),v3xOrgAccount.getId());
                    String id = attachments.get(0).getSubReference()+"";
                    map.put("数电发票附件",id);
//                    返回档案表数据
                    int updateFormNum = hxinvoiceDao.updateInvoiceDataByNoCode(formId,map);
//                    根据批次号查询是否为单一开票流程
                    String dyFlowFormId = hxinvoiceDao.getInvoiceDYFlowIdByCode(DDQQLSH,XHFSBH);
                    log.info("当前单一开票流程表单ID为"+dyFlowFormId);
                    if(!"0".equals(dyFlowFormId) && StringUtils.isNotEmpty(dyFlowFormId)){
//                        查询到当前流程号对应单一开票流程，设置返回值修改流程表单数据
                        int updateInvoiceNum = hxinvoiceDao.updateInvoiceDYFlowByCode(map.get("开票事项说明"),DDQQLSH,XHFSBH);
                        if(updateInvoiceNum==0){
                            JSONObject json = new JSONObject();
                            json.put("DDQQLSH",DDQQLSH);
                            json.put("NSRSBH",XHFSBH);
                            json.put("ZTDM","009999");
                            json.put("ZTXX","接收失败");
                            jsonres.add(json);
                            continue;
                        }
                    }else{
//                      根据批次号查询是否为批量开票流程
                        if(DDQQLSH.contains("_")){
                            String[] ddqqlshs = DDQQLSH.split("_");
                            Map<String,String> plFlowFromData = hxinvoiceDao.getInvoicePLFlowIdByCode(ddqqlshs[0],XHFSBH);
                            if(plFlowFromData!=null){
                                if(!"0".equals(plFlowFromData.get("id")) || StringUtils.isNotEmpty(plFlowFromData.get("id"))){
//                                    根据返回结果，设置返回值修改流程表数据，查询到当前流程号对应单一开票流程，设置返回值修改流程表单数据

//                                    判断返回结果是否存在对应的编号信息
                                    String[] resDatas = plFlowFromData.get("resdata").split(";");
                                    String msg = "";
                                    for (String resData: resDatas) {
                                        String[] ress = resData.split(":");
                                        if(ress[0].equals(ddqqlshs[1])){
                                            msg+=ress[0]+":"+map.get("开票事项说明")+";";
                                        }else{
                                            msg+= resData+";";
                                        }
                                    }
                                    msg = msg.substring(0,msg.length()-1);
                                    int updateInvoiceNum = hxinvoiceDao.updateInvoicePLFlowByCode(msg,DDQQLSH,XHFSBH);
                                    if(updateInvoiceNum==0){
                                        JSONObject json = new JSONObject();
                                        json.put("DDQQLSH",DDQQLSH);
                                        json.put("NSRSBH",XHFSBH);
                                        json.put("ZTDM","009999");
                                        json.put("ZTXX","接收失败");
                                        jsonres.add(json);
                                        continue;
                                    }
                                }
                            }
                        }
                    }
//                    System.out.println(formId+"修改主表数据为"+updateFormNum);
                    if(updateFormNum==0){
                        JSONObject json = new JSONObject();
                        json.put("DDQQLSH",DDQQLSH);
                        json.put("NSRSBH",XHFSBH);
                        json.put("ZTDM","009999");
                        json.put("ZTXX","接收失败");
                        jsonres.add(json);
                        continue;
                    }
                    for(int n = 0 ; n < DDMXXXS.size(); n++){
                        JSONObject DDMXXX = DDMXXXS.getJSONObject(n);
                        String SE = DDMXXX.getString("SE");
                        String SPBM = DDMXXX.getString("SPBM");
                        int num = hxinvoiceDao.updateInvoiceByGoodsCode(formId,SPBM,SE);
//                        System.out.println("修改明细表数据为"+num);
                    }
                    JSONObject json = new JSONObject();
                    json.put("DDQQLSH",DDQQLSH);
                    json.put("NSRSBH",XHFSBH);
                    json.put("ZTDM","000000");
                    json.put("ZTXX","接收成功");
                    jsonres.add(json);
                }else{
//                    System.out.println("没有查询到数据");
                    JSONObject json = new JSONObject();
                    json.put("DDQQLSH",DDQQLSH);
                    json.put("NSRSBH",XHFSBH);
                    json.put("ZTDM","009999");
                    json.put("ZTXX","接收失败");
                    jsonres.add(json);
                }
            }
        }
        JSONObject res = serReturn(jsonres,iszipCode,isencryptCode);
        log.info("开票回调处理完成后返回的json为： " + jsonres);
        return res;
    }

    @Override
    public JSONObject getInvoiceTypeParam(String methodName,Map<String,String> paramMap) throws ParseException, UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ConfigVo configVo = getHxinvoiceConfig();
        //    		secretKey
        String secretKey = configVo.getParamVal(HxinvoiceConstants.secretKey.name());
        String password = secretKey.substring(0,24);
        GzipUtils gzipUtils = new GzipUtils();
        TripleDesUtil tripleDesUtil = new TripleDesUtil();
//    		secretId
        String secretId = configVo.getParamVal(HxinvoiceConstants.secretId.name());
//    		请求类型
        String requestType  = "POST";
//    		接口地址
        String ipport = configVo.getParamVal(HxinvoiceConstants.ipport.name());
        String url = ipport+methodName;
//        System.out.println(url);
//    		设置自定义字段
        String dataExchangeId = UUIDLong.longUUID()+"";
        JSONObject contentParam = new JSONObject();
        contentParam.put("NSRSBH",paramMap.get("shuihao"));
        contentParam.put("DDQQLSH",paramMap.get("ddqqlsh"));
        contentParam.put("TQM","");
//        contentParam.put("DDH", paramMap.get("dingdan"));
        contentParam.put("DDH", "");
        contentParam.put("HZQRDBH", "");
        contentParam.put("BSWJ", "");
        contentParam.put("WJLX", "PDF");
        contentParam.put("DDRQQ", paramMap.get("ddrqq"));
        String ddrqzStr = paramMap.get("ddrqz");
//        System.out.println(paramMap.get("ddrqq")+"--"+ddrqzStr);
        Date ddrqzdate = sdf.parse(ddrqzStr);
        if(ddrqzdate.getTime()<new Date().getTime()){
            contentParam.put("DDRQZ", ddrqzStr);
        }else{
            contentParam.put("DDRQZ", sdf.format(new Date()));
        }
//        System.out.println("请求参数为："+contentParam.toString());
        byte[] src = contentParam.toString().getBytes(StandardCharsets.UTF_8);
//    		判断是否需要加密
        String encryptCode = "1";//固定为1进行加密
        byte[] bys = {};
        if("1".equals(encryptCode)){
            //		进行加密
            bys = tripleDesUtil.encryptMode(password,src);
        }
//    		判断是否需要压缩
        String zipCode = "1";//固定为1进行压缩
        byte[] gzis = bys;
        if("1".equals(zipCode)){
            //		进行压缩
            gzis = gzipUtils.compress(bys);
        }
//        System.out.println("加密完成");
//    		进行baes64加密
        String base64Encoded = Base64.encodeBase64URLSafeString(gzis);
//        System.out.println("base64Encoded:"+base64Encoded);
//    		设置签名参数
        TreeMap<String ,String> treeMap = new TreeMap<>();
        treeMap.put("content",base64Encoded);
        treeMap.put("dataExchangeId",dataExchangeId);
        treeMap.put("encryptCode",encryptCode);
        treeMap.put("secretId",secretId);
        treeMap.put("zipCode",zipCode);
        StringBuilder contentStr = new StringBuilder();
        for (String key : treeMap.keySet()) {
            contentStr.append(key+"="+treeMap.get(key)+"&");
        }
//        System.out.println("准备签名完成");
        String content = contentStr.toString();
        content = content.substring(0,content.length()-1);
        String[] urls = url.split("/");
        String uri = urls[0];
        String fuwu = "/" +urls[1];
        String path = "/"+urls[2]+"/"+urls[3]+"/";
        String banben = urls[4];
        String method = "/"+urls[5];
        String srcStr = requestType+uri+fuwu+path+banben+method+"?"+content;
//    		进行签名
        SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA1");
        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(keySpec);
        byte[] signBytes = mac.doFinal(srcStr.getBytes("UTF-8"));
//    		签名转换成字符串
        String signStr = Base64.encodeBase64URLSafeString(signBytes);
//        System.out.println("signStr:"+signStr);
//    		设置参数
        JSONObject jsonGenerateQdInvoice = new JSONObject();
        jsonGenerateQdInvoice.put("secretId",secretId);
        jsonGenerateQdInvoice.put("dataExchangeId",dataExchangeId);
        jsonGenerateQdInvoice.put("encryptCode",encryptCode);
        jsonGenerateQdInvoice.put("zipCode",zipCode);
        jsonGenerateQdInvoice.put("content",base64Encoded);
        jsonGenerateQdInvoice.put("signature",signStr);
//        System.out.println("开票请求信息："+jsonGenerateQdInvoice.toString());
        return jsonGenerateQdInvoice;
    }

    @Override
    public JSONObject queryFastRedInvoiceResult(String methodName,Map<String,String> param) throws ParseException, NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ConfigVo configVo = getHxinvoiceConfig();
        //    		secretKey
        String secretKey = configVo.getParamVal(HxinvoiceConstants.secretKey.name());
        String password = secretKey.substring(0,24);
        GzipUtils gzipUtils = new GzipUtils();
        TripleDesUtil tripleDesUtil = new TripleDesUtil();
//    		secretId
        String secretId = configVo.getParamVal(HxinvoiceConstants.secretId.name());
//    		请求类型
        String requestType  = "POST";
//    		接口地址
        String ipport = configVo.getParamVal(HxinvoiceConstants.ipport.name());
        String url = ipport+methodName;
//        System.out.println(url);
//    		设置自定义字段
        String dataExchangeId = UUIDLong.longUUID()+"";
        JSONObject contentParam = new JSONObject();
        contentParam.put("NSRSBH",param.get("nsrsbh"));
        contentParam.put("HZFPXXQRDBH",param.get("hzfpxxqrdbh"));
        contentParam.put("UUID",param.get("uuid"));
//        System.out.println("请求参数为："+contentParam.toString());
        byte[] src = contentParam.toString().getBytes(StandardCharsets.UTF_8);
//    		判断是否需要加密
        String encryptCode = "1";//固定为1进行加密
        byte[] bys = {};
        if("1".equals(encryptCode)){
            //		进行加密
            bys = tripleDesUtil.encryptMode(password,src);
        }
//    		判断是否需要压缩
        String zipCode = "1";//固定为1进行压缩
        byte[] gzis = bys;
        if("1".equals(zipCode)){
            //		进行压缩
            gzis = gzipUtils.compress(bys);
        }
//    		进行baes64加密
        String base64Encoded = Base64.encodeBase64URLSafeString(gzis);
//    		设置签名参数
        TreeMap<String ,String> treeMap = new TreeMap<>();
        treeMap.put("content",base64Encoded);
        treeMap.put("dataExchangeId",dataExchangeId);
        treeMap.put("encryptCode",encryptCode);
        treeMap.put("secretId",secretId);
        treeMap.put("zipCode",zipCode);
        StringBuilder contentStr = new StringBuilder();
        for (String key : treeMap.keySet()) {
            contentStr.append(key+"="+treeMap.get(key)+"&");
        }
//        System.out.println("准备签名完成");
        String content = contentStr.toString();
        content = content.substring(0,content.length()-1);
        String[] urls = url.split("/");
        String uri = urls[0];
        String fuwu = "/" +urls[1];
        String path = "/"+urls[2]+"/"+urls[3]+"/";
        String banben = urls[4];
        String method = "/"+urls[5];
        String srcStr = requestType+uri+fuwu+path+banben+method+"?"+content;
//    		进行签名
        SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA1");
        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(keySpec);
        byte[] signBytes = mac.doFinal(srcStr.getBytes("UTF-8"));
//    		签名转换成字符串
        String signStr = Base64.encodeBase64URLSafeString(signBytes);
//        System.out.println("signStr:"+signStr);
//    		设置参数
        JSONObject jsonGenerateQdInvoice = new JSONObject();
        jsonGenerateQdInvoice.put("secretId",secretId);
        jsonGenerateQdInvoice.put("dataExchangeId",dataExchangeId);
        jsonGenerateQdInvoice.put("encryptCode",encryptCode);
        jsonGenerateQdInvoice.put("zipCode",zipCode);
        jsonGenerateQdInvoice.put("content",base64Encoded);
        jsonGenerateQdInvoice.put("signature",signStr);
//        System.out.println("开票请求信息："+jsonGenerateQdInvoice.toString());
        log.info("开票请求信息："+jsonGenerateQdInvoice.toString());
        return jsonGenerateQdInvoice;
    }


    @Override
    public String getInvoiceContentRes(JSONObject res) throws Exception {
        ConfigVo configVo = getHxinvoiceConfig();
//        System.out.println("进行解压"+res);
        String secretKey = configVo.getParamVal(HxinvoiceConstants.secretKey.name());
        String password = secretKey.substring(0,24);
        //		压缩工具类
        GzipUtils gzipUtils = new GzipUtils();
//		加解密工具类
        TripleDesUtil tripleDesUtil = new TripleDesUtil();
//        System.out.println("获取content参数");
        String con = res.getString("content");
        byte[] decodedBytes = Base64.decodeBase64(con);
        String iszipCode = res.get("zipCode").toString();
        byte[] dec = decodedBytes;
//        System.out.println("是否进行压缩"+iszipCode);
        if("1".equals(iszipCode)){
            dec = gzipUtils.decompress(decodedBytes);
        }

//        判断是否加密
        byte[] d= dec;
        String isencryptCode = res.get("encryptCode").toString();
//        System.out.println("是否进行加密"+isencryptCode);
        if("1".equals(iszipCode)){
            d = tripleDesUtil.decryptMode(password,dec);
        }
//        编码转译
        String str = new String(d,"UTF-8");
//        System.out.println("转译之后的参数"+str);

        return str;
    }


    private JSONObject serReturn(JSONArray jsonres,String iszipCode,String isencryptCode){
        JSONObject jsonObject = new JSONObject();
        ConfigVo configVo = getHxinvoiceConfig();
        GzipUtils gzipUtils = new GzipUtils();
        TripleDesUtil tripleDesUtil = new TripleDesUtil();
        String secretKey = configVo.getParamVal(HxinvoiceConstants.secretKey.name());
        String password = secretKey.substring(0,24);
        log.info("回调完成后要返回的json: " + jsonres.toString());
        byte[] src = jsonres.toString().getBytes(StandardCharsets.UTF_8);
//    		判断是否需要加密
        String encryptCode = "1";//固定为1进行加密
        byte[] bys = {};
        if("1".equals(encryptCode)){
            //		进行加密
            bys = tripleDesUtil.encryptMode(password,src);
        }
//    		判断是否需要压缩
        String zipCode = "1";//固定为1进行压缩
        byte[] gzis = bys;
        if("1".equals(zipCode)){
            //		进行压缩
            gzis = gzipUtils.compress(bys);
        }
        String base64Encoded = Base64.encodeBase64URLSafeString(gzis);
        jsonObject.put("returnCode","000000");
        jsonObject.put("zipCode",zipCode);
        long l = UUIDLong.longUUID();
        jsonObject.put("dataExchangeId",l+"");
        jsonObject.put("returnMessage","接口请求成功");
        jsonObject.put("encryptCode",encryptCode);
        jsonObject.put("content",base64Encoded);
        return jsonObject;
    }



}
