package com.sifang.modules.bestsign.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.sifang.modules.alioss.AliyunOSSClientUtil;
import com.sifang.modules.bestsign.utils.BestSignClient;
import com.sifang.modules.sunshine.SystemSetting.utils.BusinessException;
import com.sifang.modules.sys.common.utils.StringUtil;
import com.sifang.modules.sys.common.service.BaseService;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 上上签--签约管理系列 内容
 */
@Service
public class BestSignDeltaApiService extends BaseService {


    Logger logger = LoggerFactory.getLogger(this.getClass());


    //开发者ID
    @Value("${sign.developer_id}")
    private String developerId;


    @Value("${sign.clientId}")
    private String clientId;

    //开发者私钥
    @Value("${sign.developer_privateKey}")
    private String privateKey;

    @Value("${sign.server_host}")
    private String serverHost;

    @Value("${sign.callback}")
    private String signCallback;

    @Value("${sign.secret}")
    private String secret;

    @Value("${sign.templateId}")
    private String templateId;

    @Value("${sign.roleId}")
    private String roleId;

    @Value("${sign.documentId}")
    private String documentId;

    @Value("${img.domain}")
    private String commonStaticImgPath;


    /**
     * 发送合同（新）
     * @param traderName
     * @param mobile
     * @return
     */
    public String sendContract(String traderName, String mobile, String urlPath,String fileName) throws IOException {
        JSONObject requestBody = new JSONObject();
        requestBody.put("templateId", templateId);//合同编号
        JSONArray array = new JSONArray();
        //代理商
        JSONObject rolesbject = new JSONObject();
        rolesbject.put("roleId",roleId); //签约角色

        JSONObject proxyClaimer=new JSONObject();
        proxyClaimer.put("ifProxyClaimer",false);
        rolesbject.put("proxyClaimer",proxyClaimer);

        //接收方账号信息
        JSONObject userInfo = new JSONObject();

        userInfo.put("enterpriseName",traderName); //接收方企业
        userInfo.put("userAccount", mobile);  //接收账号
        rolesbject.put("userInfo", userInfo);
        array.add(rolesbject);

    /*    //能辉自己
        JSONObject rolesbject2 = new JSONObject();
        rolesbject2.put("routeOrder","2"); //签署顺序  大于等于1，表示签署人顺序
        rolesbject2.put("roleName","能辉"); //签约角色名称
        rolesbject2.put("receiverType", "SIGNER");//签署人或抄送人 取值为签署人SIGNER或抄送人CC_USER
        rolesbject2.put("userType", "ENTERPRISE");//企业或个人 （取值为个人PERSON或企业ENTERPRISE）

        //接收方账号信息
        JSONObject userInfo2 = new JSONObject();
        userInfo2.put("userAccount", account);  //接收账号
        rolesbject2.put("userInfo", userInfo2);
        array.add(rolesbject2);
*/
        requestBody.put("roles", array);

        //合同文档集
        JSONArray documents=new JSONArray();
        JSONObject documentObject=new JSONObject();
        documentObject.put("documentId",documentId);
        URL url = new URL(commonStaticImgPath+urlPath);
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.connect();
        InputStream fis = httpConn.getInputStream();
        try(
            ByteArrayOutputStream bos = new ByteArrayOutputStream();){
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1){
                bos.write(b, 0, n);
            }
            byte[] bdata = bos.toByteArray();
            String fdata = Base64.encodeBase64String(bdata);
            documentObject.put("content",fdata);
        }catch (Exception e) {
            e.printStackTrace();
            logger.error("发起合同时，读取文件异常 e:{}",e);
            throw new BusinessException("上上签发起合同时，读取文件异常！");
        }
        documentObject.put("fileName",fileName);
        documents.add(documentObject);
        requestBody.put("documents",documents);

        requestBody.put("pushUrl", signCallback + "/main/bestSignCallBack/signedPush");
        logger.info("获取签署链接（即手动签）请求参数：{}", requestBody);
        BestSignClient bestSignClient = new BestSignClient(serverHost, clientId, secret, privateKey);
        String responseBody = bestSignClient.executeRequest("/api/templates/send-contracts-sync-v2", "POST", requestBody);
        logger.info("获取签署链接（即手动签）返回结果：{}", responseBody);
        // 返回结果解析
        JSONObject userObj = JSON.parseObject(responseBody);
        // 返回errno为0，表示成功，其他表示失败
        if ("0".equals(userObj.getString("code"))) {
            JSONObject data = userObj.getJSONObject("data");
            if (data != null) {
                return data.getString("contractId");
            }
        } else {
            logger.error(">>>>>>>>>>>>>>>>>>>>>>>>>>>createAskAuthContract e: " + userObj.get("message"));
            throw new BusinessException("发起签署失败!失败原因:" + userObj.get("message"));
        }
        return null;
    }

    /**
     * 获取合同文件签署链接
     * @return  signFlowId 发起签署 返回的 签署流程id
     */
    public Map<String,String> signUrl(String contractId){
        String uriWithParam = String.format("/api/contracts/overview/%s", contractId);
        BestSignClient bestSignClient = new BestSignClient(serverHost, developerId, secret, privateKey);
        String fileData = bestSignClient.executeRequest(uriWithParam, "GET", null);
        logger.info("获取合同签署链接结果：{}",fileData);
        JSONObject result = JSONObject.parseObject(fileData);
        if ("0".equalsIgnoreCase(result.getString("code"))) {
            JSONObject data = result.getJSONObject("data");
            if("COMPLETE".equals(data.getString("status"))){
               throw new BusinessException("合同已完成，不能获取签署链接！");
            }
            JSONArray signers = data.getJSONArray("signers");
            Map<String,String> remap = Maps.newHashMap();
            for(int i=0;i<signers.size();i++){
                JSONObject signer = (JSONObject) signers.get(i);
                String signShortUrl = signer.getString("signShortUrl"); // 本接口可以查询到轮到签署人签署时的签署链接。已签署或尚未轮到签署的，不返回签署链接。
                if(StringUtil.isNotBlank(signShortUrl)){
                    remap.put("contractUrl", signShortUrl);
                    break;
                }
            }
            return remap;
        } else {
            throw new BusinessException("获取签署失败!失败原因:" + result.get("message"));
        }
    }

    /**
     * 下载合同并上传 可下载已完成签署
     * @param contractId
     * @return
     */
    public String downloadContract(String contractId) {
        String uriWithParam = "/api/contracts/download-file";
        String fileType = "pdf";
        JSONObject postData = new JSONObject();
        postData.put("contractIds", Arrays.asList(contractId));
        postData.put("fileType", fileType);
        logger.info("下载合同请求参数：{}", postData.toJSONString());
        try {
            BestSignClient bestSignClient = new BestSignClient(serverHost, developerId, secret, privateKey);
            String fileData = bestSignClient.executeRequest(uriWithParam, "POST", postData);
            byte[] bytes = java.util.Base64.getDecoder().decode(fileData);
            //下载合同并保存
            String fileInfo= AliyunOSSClientUtil.uploadImage(bytes, "pdf", "");
            if (StringUtils.isNotBlank(fileInfo)) {
                return StringUtil.convertBackSlant(fileInfo);
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("上上签获取下载地址失败：", e);
            throw new BusinessException("上上签获取下载地址失败,失败原因："+ e.getMessage());

        }
        return "";
    }

    /**
     * 撤回未签约完成的合同
     * @param contractId
     */
    public void revoke(String contractId) {
        String uriWithParam = String.format("/api/contracts/%s/revoke", contractId);
        try {
            BestSignClient bestSignClient = new BestSignClient(serverHost, developerId, secret, privateKey);
            String response = bestSignClient.executeRequest(uriWithParam, "POST", null);
            logger.info("撤回合同结果：{}", response);
        } catch (Exception e) {
            logger.error("撤回合同失败：{}", e.getMessage());
        }
    }
}
