package com.seeyon.apps.src_hxinvoice;

import cn.hutool.log.Log;
import com.alibaba.fastjson.JSON;
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.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 org.apache.commons.codec.binary.Base64;

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 abstract class HxinvoiceCommonNode extends ACommonSuperNode {

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

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

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

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

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

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

    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();
        Cap4ReturnUtil cap4ReturnUtil = new Cap4ReturnUtil();
        FieldDataVo fhjg = formDataVo.getFieldData("电子税票系统返回结果");
        String fhvalue = fhjg.getStringValue();
        try {
            if("AddGenerateQdBdczlInvoiceNode".equals(getNodeId()) || "AddGenerateQdBdczlxzInvoiceNode".equals(getNodeId())){
//                    租金设置返回值
                String[] res = fhvalue.split(";");
                for (String re : res){
                    if(re.startsWith("租金开票请求成功")){
                        return context.success("跳过：" + re);
                    }
                }
            }else if ("AddShiChangGenerateQdInvoiceNode".equals(getNodeId()) || "AddShiChangxinzengGenerateQdInvoiceNode".equals(getNodeId())){
//                    市场费设置返回值
                String[] res = fhvalue.split(";");
                for (String re : res){
                    if(re.startsWith("市场费开票请求成功")){
                        return context.success("跳过：" + re);
                    }
                }
            }else if ("AddWuYeGenerateQdInvoiceNode".equals(getNodeId())|| "AddWuYexinzengGenerateQdInvoiceNode".equals(getNodeId())){
//                    物业费设置返回值
                String[] res = fhvalue.split(";");
                for (String re : res){
                    if(re.startsWith("物业费开票请求成功")){
                        return context.success("跳过：" + re);
                    }
                }
            }else{
                if(fhvalue.startsWith("开票请求成功")) {
                    return context.success("跳过：" + fhvalue);
                }
            }
//    		secretKey
            String secretKey = configVo.getParamVal(HxinvoiceConstants.secretKey.name());
//    		secretId
            String secretId = configVo.getParamVal(HxinvoiceConstants.secretId.name());
//    		请求类型
            String requestType  = getRequestType();
//    		接口地址
            String ipport = configVo.getParamVal(HxinvoiceConstants.ipport.name());
            String url = ipport+getMethod();
            context.setUrl(url);
//    		设置自定义字段
            String dataExchangeId = UUIDLong.longUUID()+"";
//            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());
                JSONObject content = JSONObject.parseObject(contentParam);
                JSONArray isje = content.getJSONArray("DDZXX");
                if(isje!=null){
                    if(isje.size()==0){
                        log.info("跳过开票请求成功:当前开票金额为0");
                        context.success("跳过开票请求成功:当前开票金额为0" ,false);
                        return context;
                    }
                }else{
                    log.info("跳过开票请求成功:当前开票金额为空");
                    context.success("跳过开票请求成功当前开票金额为空" ,false);
                    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);
            log.info("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);
            log.info("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);
            HxinvoiceResponse hxinvoiceResponse = HxinvoiceHttpUtil.parseResponse(str);
            if(hxinvoiceResponse.isSuccess()) {
//                cap4ReturnUtil.setParamReturn(getNodeId(),hxinvoiceResponse,formDataVo);
//                System.out.println("参数处理完成"+hxinvoiceResponse);
                log.info(hxinvoiceResponse.getData());
//                System.out.println("推送成功显示"+hxinvoiceResponse.getMsg());
                context.success("开票请求成功:" + hxinvoiceResponse.getData()+hxinvoiceResponse.getMsg(), false);
                if("AddGenerateQdBdczlInvoiceNode".equals(getNodeId()) || "AddGenerateQdBdczlxzInvoiceNode".equals(getNodeId())){
//                    租金设置返回值
                        String[] res = fhvalue.split(";");
                        String dzqsxtfhjg = "";
                        if(fhvalue.startsWith("租金开票请求")){
                            for (String re : res){
                                if(re.startsWith("租金开票请求")){
                                    dzqsxtfhjg = dzqsxtfhjg +";租金开票请求成功："+ hxinvoiceResponse.getData()+hxinvoiceResponse.getMsg()+"开票中;" ;
                                }else{
                                    dzqsxtfhjg = dzqsxtfhjg+";"+re;
                                }
                            }
                        }else{
                            dzqsxtfhjg = fhvalue+"租金开票请求成功："+ hxinvoiceResponse.getData()+hxinvoiceResponse.getMsg()+"开票中;";
                        }
                    formDataVo.getNewFieldDataMap().put("电子税票系统返回结果", dzqsxtfhjg);
                }else if ("AddShiChangGenerateQdInvoiceNode".equals(getNodeId())||"AddShiChangxinzengGenerateQdInvoiceNode".equals(getNodeId())){
//                    租金设置返回值
                    String[] res = fhvalue.split(";");
                    String dzqsxtfhjg = "";
                    if(fhvalue.startsWith("市场费开票请求")){
                        for (String re : res){
                            if(re.startsWith("市场费开票请求")){
                                dzqsxtfhjg = dzqsxtfhjg +"市场费开票请求成功："+ hxinvoiceResponse.getData()+hxinvoiceResponse.getMsg()+"开票中;" ;
                            }else{
                                dzqsxtfhjg = dzqsxtfhjg+";"+re;
                            }
                        }
                    }else{
                        dzqsxtfhjg = fhvalue +"市场费开票请求成功："+ hxinvoiceResponse.getData()+hxinvoiceResponse.getMsg()+"开票中;" ;
                    }
                    formDataVo.getNewFieldDataMap().put("电子税票系统返回结果", dzqsxtfhjg);
                }else if ("AddWuYeGenerateQdInvoiceNode".equals(getNodeId())||"AddWuYexinzengGenerateQdInvoiceNode".equals(getNodeId())){
//                    租金设置返回值
                    String[] res = fhvalue.split(";");
                    String dzqsxtfhjg = "";
                    if(fhvalue.startsWith("物业费开票请求")){
                        for (String re : res){
                            if(re.startsWith("物业费开票请求")){
                                dzqsxtfhjg = dzqsxtfhjg +"物业费开票请求成功："+ hxinvoiceResponse.getData()+hxinvoiceResponse.getMsg()+"开票中;" ;
                            }else{
                                dzqsxtfhjg = dzqsxtfhjg+re;
                            }
                        }
                    }else{
                        dzqsxtfhjg = fhvalue +"物业费开票请求成功："+ hxinvoiceResponse.getData()+hxinvoiceResponse.getMsg()+"开票中;" ;
                    }
                    formDataVo.getNewFieldDataMap().put("电子税票系统返回结果", dzqsxtfhjg);
                }else{
                    formDataVo.getNewFieldDataMap().put("电子税票系统返回结果", "开票请求成功:"+ hxinvoiceResponse.getData()+hxinvoiceResponse.getMsg()+"开票中");
                }
            }else{
                context.setErrMsg(hxinvoiceResponse.getMsg());
                context.setException(true);
                context.back("开票请求失败：" +hxinvoiceResponse.getData()+ hxinvoiceResponse.getMsg());
                if("AddGenerateQdBdczlInvoiceNode".equals(getNodeId())||"AddGenerateQdBdczlxzInvoiceNode".equals(getNodeId())){
//                    租金设置返回值
                    String[] res = fhvalue.split(";");
                    String dzqsxtfhjg = "";
                    if(fhvalue.startsWith("租金开票请求")){
                        for (String re : res){
                            if(re.startsWith("租金开票请求")){
                                dzqsxtfhjg = dzqsxtfhjg +"租金开票请求失败：" +hxinvoiceResponse.getData()+ hxinvoiceResponse.getMsg()+";" ;
                            }else{
                                dzqsxtfhjg = dzqsxtfhjg+re;
                            }
                        }
                    }else{
                        dzqsxtfhjg = fhvalue +"租金开票请求失败：" +hxinvoiceResponse.getData()+ hxinvoiceResponse.getMsg()+";" ;
                    }
                    formDataVo.getNewFieldDataMap().put("电子税票系统返回结果", dzqsxtfhjg);
                }else if ("AddShiChangGenerateQdInvoiceNode".equals(getNodeId()) || "AddShiChangxinzengGenerateQdInvoiceNode".equals(getNodeId())){
//                    租金设置返回值
                    String[] res = fhvalue.split(";");
                    String dzqsxtfhjg = "";
                    if(fhvalue.startsWith("市场费开票请求")){
                        for (String re : res){
                            if(re.startsWith("市场费开票请求")){
                                dzqsxtfhjg = dzqsxtfhjg +"市场费开票请求失败：" +hxinvoiceResponse.getData()+ hxinvoiceResponse.getMsg()+";"  ;
                            }else{
                                dzqsxtfhjg = dzqsxtfhjg+re;
                            }
                        }
                    }else{
                        dzqsxtfhjg = fhvalue +"市场费开票请求失败：" +hxinvoiceResponse.getData()+ hxinvoiceResponse.getMsg()+";"  ;
                    }
                    formDataVo.getNewFieldDataMap().put("电子税票系统返回结果", dzqsxtfhjg);
                }else if ("AddWuYeGenerateQdInvoiceNode".equals(getNodeId()) || "AddWuYexinzengGenerateQdInvoiceNode".equals(getNodeId())){
//                    租金设置返回值
                    String[] res = fhvalue.split(";");
                    String dzqsxtfhjg = "";
                    if(fhvalue.startsWith("物业费开票请求")){
                        for (String re : res){
                            if(re.startsWith("物业费开票请求")){
                                dzqsxtfhjg = dzqsxtfhjg +"物业费开票请求失败：" +hxinvoiceResponse.getData()+ hxinvoiceResponse.getMsg()+";"  ;
                            }else{
                                dzqsxtfhjg = dzqsxtfhjg+re;
                            }
                        }
                    }else{
                        dzqsxtfhjg = fhvalue +";物业费开票请求失败：" +hxinvoiceResponse.getData()+ hxinvoiceResponse.getMsg()+";"  ;
                    }
                    formDataVo.getNewFieldDataMap().put("电子税票系统返回结果", dzqsxtfhjg);
                }else{
                    formDataVo.getNewFieldDataMap().put("电子税票系统返回结果", "开票请求失败:" +hxinvoiceResponse.getData()+ hxinvoiceResponse.getMsg());
                }
            }
        }catch (Exception e) {
//            System.out.println(e.getMessage());
            e.printStackTrace();
            context.setException(true);
            context.back("开票请求失败：OA处理异常：" + e.getMessage());
            if("AddGenerateQdBdczlInvoiceNode".equals(getNodeId())  ||"AddGenerateQdBdczlxzInvoiceNode".equals(getNodeId())){
//                    租金设置返回值
                String[] res = fhvalue.split(";");
                String dzqsxtfhjg = "";
                if(fhvalue.startsWith("租金开票请求")){
                    for (String re : res){
                        if(re.startsWith("租金开票请求")){
                            dzqsxtfhjg = dzqsxtfhjg +"租金开票请求失败：" + e.getMessage()+";" ;
                        }else{
                            dzqsxtfhjg = dzqsxtfhjg+re;
                        }
                    }
                }else{
                    dzqsxtfhjg = fhvalue +";租金开票请求失败：" + e.getMessage()+";" ;
                }
                formDataVo.getNewFieldDataMap().put("电子税票系统返回结果", dzqsxtfhjg);
            }else if ("AddShiChangGenerateQdInvoiceNode".equals(getNodeId())||"AddShiChangxinzengGenerateQdInvoiceNode".equals(getNodeId())){
//                    租金设置返回值
                String[] res = fhvalue.split(";");
                String dzqsxtfhjg = "";
                if(fhvalue.startsWith("市场费开票请求")){
                    for (String re : res){
                        if(re.startsWith("市场费开票请求")){
                            dzqsxtfhjg = dzqsxtfhjg +"市场费开票请求失败：" + e.getMessage()+";"  ;
                        }else{
                            dzqsxtfhjg = dzqsxtfhjg+re;
                        }
                    }
                }else{
                    dzqsxtfhjg = fhvalue +";市场费开票请求失败：" + e.getMessage()+";"  ;
                }
                formDataVo.getNewFieldDataMap().put("电子税票系统返回结果", dzqsxtfhjg);
            }else if ("AddWuYeGenerateQdInvoiceNode".equals(getNodeId()) ||"AddWuYexinzengGenerateQdInvoiceNode".equals(getNodeId())){
//                    租金设置返回值
                String[] res = fhvalue.split(";");
                String dzqsxtfhjg = "";
                if(fhvalue.startsWith("物业费开票请求")){
                    for (String re : res){
                        if(re.startsWith("物业费开票请求")){
                            dzqsxtfhjg = dzqsxtfhjg +"物业费开票请求失败：" + e.getMessage()+";"  ;
                        }else{
                            dzqsxtfhjg = dzqsxtfhjg+re;
                        }
                    }
                }else{
                    dzqsxtfhjg = fhvalue +";物业费开票请求失败：" + e.getMessage()+";"  ;
                }
                formDataVo.getNewFieldDataMap().put("电子税票系统返回结果", dzqsxtfhjg);
            }else{
                formDataVo.getNewFieldDataMap().put("电子税票系统返回结果", "开票请求失败:OA处理异常" + e.getMessage());
            }
            return context;
        }

//        正常结束进行现成等待10秒后调用定时任务查询发票开票结果

        return context;
    }


    public abstract String getMethod();
    public abstract String getRequestType();
}
