package com.seeyon.apps.src_hxinvoice.node;


import cn.hutool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.seeyon.apps.common.config.ICstConfigApi;
import com.seeyon.apps.common.plugin.vo.ConfigVo;
import com.seeyon.apps.common.workflow.constants.WorkFlowType;
import com.seeyon.apps.common.workflow.node.ACommonSuperNode;
import com.seeyon.apps.ext.workflow.vo.FieldDataVo;
import com.seeyon.apps.ext.workflow.vo.FormDataVo;
import com.seeyon.apps.ext.workflow.vo.SuperNodeContext;
import com.seeyon.apps.src_hxinvoice.constants.HxinvoiceConstants;
import com.seeyon.apps.src_hxinvoice.util.*;
import com.seeyon.apps.src_hxinvoice.vo.HxinvoiceResponse;
import com.seeyon.cap4.form.api.FormDataApi4Cap4;
import com.seeyon.cap4.form.bean.FormDataMasterBean;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.util.UUIDLong;
import com.seeyon.ctp.util.json.JSONUtil;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.TreeMap;

/**
 * 功能描述:<br>
 * <pre>
 *
 * </pre>
 *
 * @Author: HuangZhengguo
 * @Date: 2024/4/28
 */
public class AddOrderToFastRedInvoiceNode extends ACommonSuperNode {

    private static Log log = Log.get(AddOrderToFastRedInvoiceNode.class);

    public String getMethod() {
        return "/sims-api/invoice/api/v6/OrderToFastRedInvoice";
    }

    protected ICstConfigApi cstConfigApi = (ICstConfigApi) AppContext.getBean("cstConfigApi");

    @Override
    public String getNodeId() {
        return "AddOrderToFastRedInvoiceNode";
    }

    @Override
    public String getNodeName() {
        return "数电订单快捷冲红接口";
    }

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

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

    @Override
    public String getFormParse()  {
        return "json";
    }

    @Override
    public WorkFlowType[] getTypes()  {
        return new WorkFlowType[] {WorkFlowType.superNode};
    }

    protected FormDataApi4Cap4 formDataApi4Cap4;

    public void setFormDataApi4Cap4(FormDataApi4Cap4 formDataApi4Cap4) {
        this.formDataApi4Cap4 = formDataApi4Cap4;
    }


    @Override
    public SuperNodeContext proceed(String request, FormDataVo formDataVo, FormDataMasterBean formDataMasterBean) throws Exception {
        ConfigVo configVo = getHxinvoiceConfig();
        SuperNodeContext context = new SuperNodeContext();
        FieldDataVo fhjg = formDataVo.getFieldData("电子税票系统返回结果");
        String fhvalue = fhjg.getStringValue();
        try {
            if(fhvalue.startsWith("冲红请求成功")) {
               return context.wait("跳过：" + fhvalue);
            }
            FieldDataVo hzqrdidvo = formDataVo.getFieldData("红字确认单ID");
            String hzqrdid = hzqrdidvo.getStringValue();
            if(StringUtils.isNotEmpty(hzqrdid)){
                return context.wait("等待确定处理：正在开具当前红字发票请等待开票完成，"+fhvalue);
            }
//    		secretKey
            String secretKey = configVo.getParamVal(HxinvoiceConstants.secretKey.name());
//    		secretId
            String secretId = configVo.getParamVal(HxinvoiceConstants.secretId.name());
//    		请求类型
            String requestType  = "POST";
//    		接口地址
            String ipport = configVo.getParamVal(HxinvoiceConstants.ipport.name());
//            获取冲红接口地址
            String url = ipport+getMethod();
            context.setUrl(url);
//    		设置自定义字段
            String dataExchangeId = UUIDLong.longUUID()+"";
            log.info("设置冲红基础参数");
//            System.out.println("设置冲红基础参数");
//            ProtUtil protUtil = new ProtUtil();
            String password =secretKey.substring(0,24);
//    		压缩工具类
            GzipUtils gzipUtils = new GzipUtils();
//    		加解密工具类
            TripleDesUtil tripleDesUtil = new TripleDesUtil();
            ParamUtil paramUtil = new ParamUtil();
//            System.out.println("获取参数");
            log.info("处理前参数："+request);
            String contentParam ="";
            if(!"{}".equals(request)){
                contentParam = paramUtil.handleRequestParam(formDataVo,request,getNodeId());
            }else{
                context.back("冲红请求失败：OA处理异常：参数处理异常");
                formDataVo.getNewFieldDataMap().put("电子税票系统返回结果", "冲红请求失败：OA处理异常：参数处理异常");
                return context;
            }
            if(!contentParam.contains("{")){
                context.back("冲红请求失败：OA处理异常：" + contentParam);
                formDataVo.getNewFieldDataMap().put("电子税票系统返回结果", "冲红请求失败：OA处理异常："+contentParam);
                return context;
            }
            context.setRequest(contentParam);
            context.setNeedSave(true);
            byte[] src = contentParam.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("准备调用");
//            JSONObject res = protUtil.doPost(jsonGenerateQdInvoice.toString(),"http://"+url);
            String response = HxinvoiceHttpUtil.doPost("http://"+url, jsonGenerateQdInvoice.toString());
//            System.out.println(response);
            JSONObject resjson = JSON.parseObject(response);
//            System.out.println("调用完成");
            String con = resjson.getString("content");
            byte[] decodedBytes = Base64.decodeBase64(con);
            String iszipCode = resjson.getString("zipCode");
            String isencryptCode = resjson.getString("encryptCode");
//            是否需要进行解压
            byte[] dec = decodedBytes;
            if("1".equals(iszipCode)){
                dec = gzipUtils.decompress(decodedBytes);
            }
//            是否需要进行解密
            byte[] d= dec;
            if("1".equals(isencryptCode)){
                d = tripleDesUtil.decryptMode(password,dec);
            }
            String str = new String(d,"UTF-8");
            context.setResponse(str);
            JSONObject object = JSONUtil.parseJSONString(str, JSONObject.class);
            HxinvoiceResponse hxinvoiceResponse = new HxinvoiceResponse(object,getMethod());

            if(hxinvoiceResponse.isSuccess()) {
                JSONObject ret = JSONObject.parseObject(str);
                log.info(hxinvoiceResponse.getData());
                log.info("推送成功显示"+hxinvoiceResponse.getMsg());
                context.wait("开票请求成功:" +hxinvoiceResponse.getMsg(), false);
                formDataVo.getNewFieldDataMap().put("红字确认单编号", ret.getString("HZFPXXQRDBH"));
                formDataVo.getNewFieldDataMap().put("红字确认单ID", ret.getString("UUID"));
                formDataVo.getNewFieldDataMap().put("token", formDataVo.getToken());
                formDataVo.getNewFieldDataMap().put("电子税票系统返回结果", "开票请求成功:"+hxinvoiceResponse.getMsg());
                formDataVo.getNewFieldDataMap().put("订单状态描述", "开票请求成功:"+hxinvoiceResponse.getMsg());
            }else{
                context.setErrMsg(hxinvoiceResponse.getMsg());
                context.setException(true);
                context.back("开票请求失败：" +hxinvoiceResponse.getData()+ hxinvoiceResponse.getMsg());
                formDataVo.getNewFieldDataMap().put("token", formDataVo.getToken());
                formDataVo.getNewFieldDataMap().put("电子税票系统返回结果", "开票请求失败:" +hxinvoiceResponse.getMsg());
                formDataVo.getNewFieldDataMap().put("订单状态描述", "开票请求失败:" +hxinvoiceResponse.getMsg());
            }
        }catch (Exception e) {
//            System.out.println(e.getMessage());
            e.printStackTrace();
            context.setException(true);
            context.back("开票请求失败：OA处理异常：" + e.getMessage());
            formDataVo.getNewFieldDataMap().put("电子税票系统返回结果", "开票请求失败:OA处理异常" + e.getMessage());
            formDataVo.getNewFieldDataMap().put("订单状态描述", "开票请求失败:OA处理异常" + e.getMessage());
            return context;
        }
        return context;
    }
}
