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 com.weaver.seconddev.chapanda.esign.entity.OkHttpDto;
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.beans.factory.annotation.Autowired;
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 Esb2EsignApplyRequest4OrgainzeUtil {
    private final static Logger log = LoggerFactory.getLogger(Esb2EsignApplyRequest4OrgainzeUtil.class);
    @Autowired
    Esb2EsignTemplateSealPostionUtil esb2EsignTemplateSealPostionUtil;
    public OkHttpDto applyRequest(String requestid,String requestname,String templateId,String sealId,String docFilekey,String docName,String creditCode,String qsrJobNum){

        JSONArray signDocs = new JSONArray();
        JSONObject signDoc = new JSONObject();
        signDoc.put("docFilekey",docFilekey);
        signDoc.put("docName",docName);
        signDoc.put("docOrder",1);
        signDocs.add(signDoc);

        JSONArray signers = appendSignersParty(templateId,sealId,docFilekey,creditCode,qsrJobNum);
        log.error("signers:{}",signers.toJSONString());
        JSONObject bodyJson = new JSONObject();
        bodyJson.put("bizNo",requestid);
        bodyJson.put("callbackUrl",Constants.callbackUrl);
        bodyJson.put("initiatorUniqueId","admin");
        bodyJson.put("qrDocSwitcher",Constants.qrDocSwitcher);
        bodyJson.put("signDocs",signDocs);
        bodyJson.put("signFileFormat",Constants.signFileFormat);
        bodyJson.put("signers",signers);
        bodyJson.put("subject",requestname);

        String xTimevaleSignature = encryptionHmacSHA256(bodyJson.toJSONString());
        log.error("xTimevaleSignature:"+xTimevaleSignature);

        OkHttpDto okHttpDto = doHttpPost(xTimevaleSignature,bodyJson.toJSONString());
//        if(StringUtils.isNotBlank(msg)){
//            returnJson = convertData(msg);
//        }
        return okHttpDto;
    }


    /**
     *
     * @param xTimevaleSignature
     * @param bodyData
     * @return
     */
    public OkHttpDto doHttpPost(String xTimevaleSignature,String bodyData){
        log.error("bodyData:{}",bodyData);
        OkHttpDto okHttpDto = new OkHttpDto();
        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.signFlowsUrl)
                    .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();
            String msg = response.body().string();
            log.error("code:{}",code);
            log.error("msg:{}",msg);
            okHttpDto.setResponseCode(code);
            okHttpDto.setResponseBody(msg);
            convertData(msg,okHttpDto);
        } catch (IOException e) {
            log.error("e:"+e.getMessage());
            throw new RuntimeException(e);
        }
        return okHttpDto;
    }

    /***
     *
     * @param bodyData
     * @return
     */
    public String encryptionHmacSHA256(String bodyData){
        String encryptionData = "";
        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 JSONArray appendSignersParty(String templateId,String sealId,String docFilekey,String creditCode,String qsrJobNum){
        JSONArray signers = new JSONArray();
        JSONObject detailJson = esb2EsignTemplateSealPostionUtil.getTemplateFormData4Orgainze(templateId,sealId,docFilekey);
        log.error("detailJson:{}",detailJson.toJSONString());

        JSONObject partyAJson = new JSONObject();
        partyAJson.put("authorizationOrganizeNo",creditCode);
        partyAJson.put("uniqueId",qsrJobNum);
        partyAJson.put("accountType",Constants.partyAaccountType);
        partyAJson.put("autoSign","true");
        partyAJson.put("signOrder","1");

        if(detailJson.containsKey("partyA")){
            JSONArray partyA = detailJson.getJSONArray("partyA");
            partyAJson.put("signDocDetails",partyA);
        }

        log.error("partyAJson:{}",partyAJson.toJSONString());
        signers.add(partyAJson);
        return signers;
    }


    public void convertData(String reposponseBody,OkHttpDto okHttpDto){

        JSONObject bodyJson = JSONObject.parseObject(reposponseBody);
        int errCode = -100;
        if(bodyJson.containsKey("errCode")){
            errCode = bodyJson.getInteger("errCode");
            log.error("errCode:{}",errCode);
        }
        okHttpDto.setDataCode(errCode);
        String msg = "";
        if(bodyJson.containsKey("msg")){
            msg = bodyJson.getString("msg");
            log.error("msg:{}",msg);
        }
        okHttpDto.setDataMsg(msg);

        if(errCode == 0){
            JSONObject dataObject = new JSONObject();
            if(bodyJson.containsKey("data")){
                JSONObject dataJson = bodyJson.getJSONObject("data");
                if(dataJson.containsKey("signFlowId")){
                    String signFlowId = dataJson.getString("signFlowId");
                    log.error("signFlowId:{}",signFlowId);

                    dataObject.put("signFlowId",signFlowId);

                    String signUrls = "";
                    String uniqueIds = "";
                    String accountIds = "";

                    if(dataJson.containsKey("signUrls")){
                        String signUrlsStr = dataJson.getString("signUrls");
                        log.error("signUrlsStr:{}",signUrlsStr);
                        if(!"[]".equals(signUrlsStr)){
                            JSONArray signUrlsArray = dataJson.getJSONArray("signUrls");
                            for(int i=0;i<signUrlsArray.size();i++){
                                JSONObject signUrlJson = signUrlsArray.getJSONObject(i);
                                String signUrl = signUrlJson.getString("signUrl");
                                String uniqueId = signUrlJson.getString("uniqueId");
                                String accountId = signUrlJson.getString("accountId");
                                signUrls += StringUtils.isBlank(signUrls) ? signUrl : ","+signUrl ;
                                uniqueIds += StringUtils.isBlank(uniqueIds) ? uniqueId : ","+uniqueId ;
                                accountIds += StringUtils.isBlank(accountIds) ? accountId : ","+accountId ;
                            }
                        }
                    }

                    String fileKeys = "";
                    if(dataJson.containsKey("signDocs")){
                        String signDocsStr = dataJson.getString("signDocs");
                        log.error("signDocsStr:{}",signDocsStr);
                        if(!"[]".equals(signDocsStr)){
                            JSONArray signDocs = dataJson.getJSONArray("signDocs");
                            for(int i=0;i<signDocs.size();i++){
                                JSONObject signDoc = signDocs.getJSONObject(i);
                                String fileKey = signDoc.getString("fileKey");
                                log.error("fileKey:{}",fileKey);
                                fileKeys += StringUtils.isBlank(fileKeys) ? fileKey : ","+fileKey ;
                            }
                        }
                    }

                    log.error("fileKeys:{}",fileKeys);

                    dataObject.put("signUrls",signUrls);
                    dataObject.put("accountIds",accountIds);
                    dataObject.put("uniqueIds",uniqueIds);
                    dataObject.put("fileKeys",fileKeys);
                }
            }
            okHttpDto.setDataJson(dataObject);
        }
//        if(bodyJson.containsKey("errCode")){
//            String errCode = bodyJson.getString("errCode");
//            if("0".equals(errCode)){
//
//            }
//        }
    }
}
