package com.weaver.seconddev.chapanda.esign.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.weaver.seconddev.chapanda.esign.constant.Constants;
import okhttp3.*;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

@Component
public class Esb2EsignTemplateSealPostionUtil {
    private final static Logger log = LoggerFactory.getLogger(Esb2EsignTemplateSealPostionUtil.class);

    public JSONObject getTemplateFormData(String templateId,String sealId,String docFilekey){

        JSONObject detailJson = new JSONObject();


        JSONObject partyA = new JSONObject();
        JSONObject partyB = new JSONObject();

        JSONObject bodyJson = new JSONObject();
        bodyJson.put("templateId", templateId);

        String xTimevaleSignature = encryptionHmacSHA256(bodyJson.toJSONString());
        log.error("xTimevaleSignature:"+xTimevaleSignature);
        String msg = doPostHttp(xTimevaleSignature,bodyJson.toJSONString());
        log.error("msg:"+msg);
        if(StringUtils.isNotBlank(msg)){
            JSONObject msgJson = JSONObject.parseObject(msg);
            if(msgJson.containsKey("errCode")){
                String errCode = msgJson.getString("errCode");
                if("0".equals(errCode)){
                    if(msgJson.containsKey("data")){
                        JSONObject dataJson = msgJson.getJSONObject("data");
                        if(dataJson.containsKey("template")){
                            JSONObject templateJson = dataJson.getJSONObject("template");
                            if(templateJson.containsKey("templateFlows")){
                                JSONArray templateFlows = templateJson.getJSONArray("templateFlows");

                                for(int i=0;i<templateFlows.size();i++){
                                    JSONObject templateFlowJson = templateFlows.getJSONObject(i);
                                    if(templateFlowJson.containsKey("flowName")){
                                        String flowName = templateFlowJson.getString("flowName");
                                        if("甲方".equals(flowName)){

                                            JSONObject predefineJson = templateFlowJson.getJSONObject("predefine");
                                            boolean addSignTime = predefineJson.getBoolean("addSignTime");
                                            JSONArray positionsArray = predefineJson.getJSONArray("positions");
                                            System.out.println("positionsArray:"+positionsArray);

                                            JSONArray signPos = new JSONArray();

                                            for(int k=0;k<positionsArray.size();k++){
                                                JSONObject positionsJson = positionsArray.getJSONObject(k);
                                                String posX = positionsJson.getString("posX");
                                                String posY = positionsJson.getString("posY");
                                                String pageNo = positionsJson.getString("pageNo");

                                                JSONArray signDateInfos = new JSONArray();


                                                if(positionsJson.containsKey("templateSignTimeInfos")){
                                                    if(!"[]".equals(positionsJson.getString("templateSignTimeInfos").trim())){
                                                        JSONArray templateSignTimeInfosArray = positionsJson.getJSONArray("templateSignTimeInfos");
                                                        for(int n=0;n<templateSignTimeInfosArray.size();n++){
                                                            JSONObject templateSignTimeInfosJson = templateSignTimeInfosArray.getJSONObject(n);
                                                            JSONObject signDateInfo = new JSONObject();
                                                            signDateInfo.put("dateFormat",templateSignTimeInfosJson.getString("dateFormat"));
                                                            signDateInfo.put("fontSize",templateSignTimeInfosJson.getString("fontSize"));
                                                            signDateInfo.put("posPage",templateSignTimeInfosJson.getString("posPage"));
                                                            signDateInfo.put("posX",templateSignTimeInfosJson.getString("posX"));
                                                            signDateInfo.put("posY",templateSignTimeInfosJson.getString("posY"));
                                                            signDateInfos.add(signDateInfo);
                                                        }
                                                    }
                                                }



                                                JSONObject signPo = new JSONObject();
                                                signPo.put("addSignTime",addSignTime);
                                                signPo.put("edgePosition",1);
                                                signPo.put("edgeScope",0);
                                                signPo.put("posX",posX);
                                                signPo.put("posY",posY);
                                                signPo.put("posPage",pageNo);
                                                signPo.put("signDateInfos",signDateInfos);

                                                signPo.put("sealId",sealId);
                                                signPo.put("signIdentity","ORGANIZE");
                                                signPo.put("signType",2);
                                                signPos.add(signPo);
                                            }


                                            partyA.put("signPos",signPos);
                                            partyA.put("docFilekey",docFilekey);
                                        }else if("乙方".equals(flowName)){
                                            JSONObject predefineJson = templateFlowJson.getJSONObject("predefine");
                                            boolean addSignTime = predefineJson.getBoolean("addSignTime");
                                            JSONArray positionsArray = predefineJson.getJSONArray("positions");
                                            System.out.println("positionsArray:"+positionsArray);

                                            JSONArray signPos = new JSONArray();

                                            for(int k=0;k<positionsArray.size();k++){
                                                JSONObject positionsJson = positionsArray.getJSONObject(k);
                                                String posX = positionsJson.getString("posX");
                                                String posY = positionsJson.getString("posY");
                                                String pageNo = positionsJson.getString("pageNo");

                                                JSONArray signDateInfos = new JSONArray();
                                                if(positionsJson.containsKey("templateSignTimeInfos")){
                                                    if(!"[]".equals(positionsJson.getString("templateSignTimeInfos").trim())){
                                                        JSONArray templateSignTimeInfosArray = positionsJson.getJSONArray("templateSignTimeInfos");
                                                        for(int n=0;n<templateSignTimeInfosArray.size();n++){
                                                            JSONObject templateSignTimeInfosJson = templateSignTimeInfosArray.getJSONObject(n);
                                                            JSONObject signDateInfo = new JSONObject();
                                                            signDateInfo.put("dateFormat",templateSignTimeInfosJson.getString("dateFormat"));
                                                            signDateInfo.put("fontSize",templateSignTimeInfosJson.getString("fontSize"));
                                                            signDateInfo.put("posPage",templateSignTimeInfosJson.getString("posPage"));
                                                            signDateInfo.put("posX",templateSignTimeInfosJson.getString("posX"));
                                                            signDateInfo.put("posY",templateSignTimeInfosJson.getString("posY"));
                                                            signDateInfos.add(signDateInfo);
                                                        }
                                                    }
                                                }


                                                JSONObject signPo = new JSONObject();
                                                signPo.put("addSignTime",addSignTime);
                                                signPo.put("edgePosition",1);
                                                signPo.put("edgeScope",0);
                                                signPo.put("posX",posX);
                                                signPo.put("posY",posY);
                                                signPo.put("posPage",pageNo);
                                                if(signDateInfos.size() > 0){
                                                    signPo.put("signDateInfos",signDateInfos);
                                                }
                                                signPo.put("signIdentity","PERSON");
                                                signPo.put("sealType","0");
                                                signPo.put("signType",2);

                                                signPos.add(signPo);
                                            }
                                            partyB.put("signPos",signPos);
                                            partyB.put("docFilekey",docFilekey);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        JSONArray signDocPartyA = new JSONArray();
        signDocPartyA.add(partyA);
        JSONArray signDocPartyB = new JSONArray();
        signDocPartyB.add(partyB);

        detailJson.put("partyA",signDocPartyA);
        detailJson.put("partyB",signDocPartyB);
        return detailJson;
    }


    /***
     *
     * @param xTimevaleSignature
     * @return
     */
    public String doPostHttp(String xTimevaleSignature,String bodyData){
        OkHttpClient client = new OkHttpClient().newBuilder()
                .build();
        MediaType mediaType = MediaType.parse("application/json");

        RequestBody body = RequestBody.create(mediaType,bodyData);

        try {
            Request request = new Request.Builder()
                    .url(Constants.eSignHost+Constants.getTemplateInfoUrl)
                    .method("POST", body)
                    .addHeader("x-timevale-project-id", Constants.xTimevaleProjectId)
                    .addHeader("x-timevale-signature", xTimevaleSignature)
                    .addHeader("Content-Type", "application/json")
                    .build();
            Response response = client.newCall(request).execute();
            int code = response.code();
            bodyData =  response.body().string();
            log.error("code:{}",code);
            log.error("bodyData:{}",bodyData);
        } catch (IOException e) {
            log.error("e:"+e.getMessage());
            throw new RuntimeException(e);
        }
        return bodyData;
    }

    /***
     *
     * @param bodyData
     * @return
     */
    public String encryptionHmacSHA256(String bodyData){
        String encryptionData = "";
//        String secretKey = "7f067a08f5c675137e6e72aa298e2c07";
        // 要签名的数据
//        JSONObject dataObject = new JSONObject();
//        dataObject.put("templateId","JMHT-ZXSJ");
//        String data = "{\"templateId\":\"JMHT-ZXSJ\"}" ;
        try {
            // 初始化Mac对象
            Mac sha256Hmac = Mac.getInstance("HmacSHA256");
            SecretKeySpec secretKeySpec = new SecretKeySpec(Constants.secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
            sha256Hmac.init(secretKeySpec);
            byte[] result = sha256Hmac.doFinal(bodyData.getBytes(StandardCharsets.UTF_8));
            encryptionData = Hex.encodeHexString(result);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }catch (InvalidKeyException e) {
            throw new RuntimeException(e);
        }
        return encryptionData;
    }



    public JSONObject getTemplateFormData4Orgainze(String templateId,String sealId,String docFilekey){

        JSONObject detailJson = new JSONObject();

        JSONObject partyA = new JSONObject();

        JSONObject bodyJson = new JSONObject();
        bodyJson.put("templateId", templateId);

        String xTimevaleSignature = encryptionHmacSHA256(bodyJson.toJSONString());
        log.error("xTimevaleSignature:"+xTimevaleSignature);
        String msg = doPostHttp(xTimevaleSignature,bodyJson.toJSONString());
        log.error("msg:"+msg);
        if(StringUtils.isNotBlank(msg)){
            JSONObject msgJson = JSONObject.parseObject(msg);
            if(msgJson.containsKey("errCode")){
                String errCode = msgJson.getString("errCode");
                if("0".equals(errCode)){
                    if(msgJson.containsKey("data")){
                        JSONObject dataJson = msgJson.getJSONObject("data");
                        if(dataJson.containsKey("template")){
                            JSONObject templateJson = dataJson.getJSONObject("template");
                            if(templateJson.containsKey("templateFlows")){
                                JSONArray templateFlows = templateJson.getJSONArray("templateFlows");
                                log.error("templateFlows:{}",templateFlows);
                                for(int i=0;i<templateFlows.size();i++){
                                    JSONObject templateFlowJson = templateFlows.getJSONObject(i);
                                    if(templateFlowJson.containsKey("flowName")){
                                        String flowName = templateFlowJson.getString("flowName");
                                        log.error("flowName:{}",flowName);
                                        if("公司盖章处".equals(flowName)){

                                            JSONObject predefineJson = templateFlowJson.getJSONObject("predefine");
                                            boolean addSignTime = predefineJson.getBoolean("addSignTime");
                                            JSONArray positionsArray = predefineJson.getJSONArray("positions");
                                            log.error("positionsArray:{}",positionsArray.size());
                                            JSONArray signPos = new JSONArray();

                                            for(int k=0;k<positionsArray.size();k++){
                                                JSONObject positionsJson = positionsArray.getJSONObject(k);
                                                String posX = positionsJson.getString("posX");
                                                String posY = positionsJson.getString("posY");
                                                String pageNo = positionsJson.getString("pageNo");
                                                log.error("posX:{}",posX);
                                                log.error("posY:{}",posY);
                                                log.error("pageNo:{}",pageNo);

                                                JSONArray signDateInfos = new JSONArray();
                                                if(positionsJson.containsKey("templateSignTimeInfos")){
                                                    if(!"[]".equals(positionsJson.getString("templateSignTimeInfos").trim())){
                                                        JSONArray templateSignTimeInfosArray = positionsJson.getJSONArray("templateSignTimeInfos");
                                                        for(int n=0;n<templateSignTimeInfosArray.size();n++){
                                                            JSONObject templateSignTimeInfosJson = templateSignTimeInfosArray.getJSONObject(n);
                                                            JSONObject signDateInfo = new JSONObject();
                                                            signDateInfo.put("dateFormat",templateSignTimeInfosJson.getString("dateFormat"));
                                                            signDateInfo.put("fontSize",templateSignTimeInfosJson.getString("fontSize"));
                                                            signDateInfo.put("posPage",templateSignTimeInfosJson.getString("posPage"));
                                                            signDateInfo.put("posX",templateSignTimeInfosJson.getString("posX"));
                                                            signDateInfo.put("posY",templateSignTimeInfosJson.getString("posY"));
                                                            signDateInfos.add(signDateInfo);
                                                        }
                                                    }
                                                }
                                                log.error("signDateInfos:{}",signDateInfos.size());
                                                JSONObject signPo = new JSONObject();
                                                signPo.put("addSignTime",addSignTime);
                                                signPo.put("edgePosition",1);
                                                signPo.put("edgeScope",0);
                                                signPo.put("posX",posX);
                                                signPo.put("posY",posY);
                                                signPo.put("posPage",pageNo);
                                                if(signDateInfos.size()>0){
                                                    signPo.put("signDateInfos",signDateInfos);
                                                }

                                                signPo.put("sealId",sealId);
                                                signPo.put("signIdentity","ORGANIZE");
                                                signPo.put("signType",1);
                                                signPos.add(signPo);
                                            }

                                            partyA.put("signPos",signPos);
                                            log.error("docFilekey:{}",docFilekey);
                                            partyA.put("docFilekey",docFilekey);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        JSONArray signDocPartyA = new JSONArray();
        signDocPartyA.add(partyA);
        detailJson.put("partyA",signDocPartyA);
        return detailJson;
    }



}
