package com.sifang.modules.esign.service;

import com.google.common.collect.Lists;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.alioss.AliyunOSSClientUtil;
import com.sifang.modules.config.EsignConfig;
import com.sifang.modules.contract.dao.TraderContractTemplateDao;
import com.sifang.modules.contract.entity.TraderContractTemplate;
import com.sifang.modules.customer.Service.CustomerEntryMsgService;
import com.sifang.modules.customer.constant.CustomerEntryConstants;
import com.sifang.modules.customer.dao.CustomerEntryDao;
import com.sifang.modules.customer.entity.CustomerEntry;
import com.sifang.modules.esign.cn.tsign.hz.comm.EsignHttpHelper;
import com.sifang.modules.esign.cn.tsign.hz.comm.EsignHttpResponse;
import com.sifang.modules.esign.cn.tsign.hz.enums.EsignRequestType;
import com.sifang.modules.esign.cn.tsign.hz.exception.EsignDemoException;
import com.sifang.modules.esign.constants.ESignConstants;
import com.sifang.modules.esign.vo.ComponentVo;
import com.sifang.modules.esign.vo.FileVo;
import com.sifang.modules.sunshine.SystemSetting.utils.BusinessException;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.sys.common.persistence.Parameter;
import com.sifang.modules.sys.common.service.BaseService;
import com.sifang.modules.sys.common.utils.DateUtils;
import com.sifang.modules.sys.entity.Operator;
import com.sifang.modules.sys.util.GuardUtils;
import org.hibernate.SQLQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;

@Component
public class RedSunAskAuthContractService extends BaseService {
    private static Logger logger= LoggerFactory.getLogger(RedSunAskAuthContractService.class);

    @Autowired
    private TraderContractTemplateDao templateDao;

    @Autowired
    CustomerEntryDao customerDao;

    @Autowired
    CustomerEntryMsgService msgService;

    @Autowired
    private CustomerEntryDao customerEntryDao;
//    @Value("${esign.devel}")
//    private boolean eSign;


    private static String eSignHost= EsignConfig.EsignHost;
    private static String eSignAppId=EsignConfig.EsignAppId;
    private static String eSignAppSecret=EsignConfig.EsignAppSecret;

    public static String docTemplateName="信息使用授权协议";

    public static String contractName="信息使用授权协议";

    //邀请农户授权
    public  String createAskAuthContract(String idCode,String mobile, String address,String partner_id){


        List<ComponentVo> componentS = Lists.newArrayList();
        //获取模板
        TraderContractTemplate   template = templateDao.getByHql("from TraderContractTemplate where status='0' and type='3' and patern=:p1",new Parameter(partner_id));
        if(template == null){
            throw new BusinessException("请先维护合同模板");
        }
        if(StringUtil.isBlank(idCode)){
            throw new BusinessException("请先维护农户身份证!");
        }
        if(StringUtil.isBlank(mobile)){
            throw new BusinessException("请先维护农户手机号!");
        }

        ComponentVo vo1 = new ComponentVo();
        vo1.setComponentKey("idCard");
        vo1.setComponentValue(idCode);
        componentS.add(vo1);
        String yearD= DateUtils.getYear();
        String monthD = DateUtils.getMonth();
        String dayD =DateUtils.getDay();
        ComponentVo year = new ComponentVo();
        year.setComponentKey("year");
        year.setComponentValue(yearD);
        componentS.add(year);
        ComponentVo mmo = new ComponentVo();
        mmo.setComponentKey("month");
        mmo.setComponentValue(monthD);
        componentS.add(mmo);
        ComponentVo day = new ComponentVo();
        day.setComponentKey("day");
        day.setComponentValue(dayD);
        componentS.add(day);

        if(!"01".equals(partner_id)){

            if(StringUtil.isBlank(address)){
                throw new BusinessException("请先维护单位通信地址!");
            }
            ComponentVo vo2 = new ComponentVo();
            vo2.setComponentKey("address");
            vo2.setComponentValue(address);
            componentS.add(vo2);
            ComponentVo vo4 = new ComponentVo();
            vo4.setComponentKey("mobile");
            vo4.setComponentValue(mobile);
            componentS.add(vo4);
        }

        logger.info("eSignHost : {} eSignAppId {}, eSignAppSecret:{} ",eSignHost,eSignAppId, eSignAppSecret);
        //未邀请，流程ID为空
        try {
            Map<String, Object> param = new HashMap<>();

            //填写模板生成文件(生成的就是合同文件)
            FileVo fileVo = ESignFileService.createByDocTemplate(template.getDocTemplateId(), docTemplateName, componentS);
            //基于文件发起签署---获取到流程ID
            String fileId=fileVo.getFileId();
            String apiaddr = "/v3/sign-flow/create-by-file";
            // 设置待签署文件信息
            List<Map<String, Object>> docs = new ArrayList<>();
            Map<String, Object> doc = new HashMap<>();
            doc.put("fileId", fileId);
            doc.put("fileName", contractName);
            docs.add(doc);
            // 签署流程配置项
            Map<String, Object> signFlowConfig = new HashMap<>();
            signFlowConfig.put("signFlowTitle", contractName); //签署流程主题
            signFlowConfig.put("autoStart", true); //自动开启签署流程，默认值 true    false - 非自动开启 需调用【开启签署流程】接口后流程进入“签署中”状态
            signFlowConfig.put("autoFinish", true);  //所有签署方签署完成后流程自动完结，默认值 false  true - 自动完结   false - 非自动完结，需调用【完结签署流程】接口完结
            signFlowConfig.put("notifyUrl", EsignConfig.NotifyUrl+"/a/main/sign/authTenantCallBack");   //接收相关回调通知的Web地址
            Map<String, Object> redirectConfig = new HashMap<>();
            redirectConfig.put("redirectUrl", EsignConfig.NotifyUrl+"/a/main/redirect/eSignSuccess");  // 签署完成后跳转页面（需符合 https /http 协议地址）
            signFlowConfig.put("redirectConfig", redirectConfig);
            Map<String, Object> noticeConfig = new HashMap<>();
            noticeConfig.put("noticeTypes","");
            signFlowConfig.put("noticeConfig",noticeConfig);
//            if(eSign){ // 调用思方版本的E签宝 需要执行下面代码
//                Map<String, Object> chargeConfig = new HashMap<>();
//                chargeConfig.put("chargeMode","1");
//                chargeConfig.put("orderType","DISTRIBUTION");
//                signFlowConfig.put("chargeConfig",chargeConfig);
//
//                Map<String, Object> signFlowInitiator = new HashMap<>();
//                Map<String, Object> orgInitiator = new HashMap<>();
//                orgInitiator.put("orgId","524dce5a878a4e0e869cb52535a84f0a");
//                Map<String, Object> transactor = new HashMap<>();
//                transactor.put("psnId","74367a7008ab4b129c0f5e2ca32e4d26");
//                orgInitiator.put("transactor",transactor);
//                signFlowInitiator.put("orgInitiator",orgInitiator);
//                param.put("signFlowInitiator", signFlowInitiator);
//            }


            //签署方信息 双方签署
            List<Map<String, Object>> signers = new ArrayList<>();

            // 农户信息
            Map<String, Object> signerP = new HashMap<>();
            signerP.put("signerType", 0);

            Map<String, Object> psnSignerInfo = new HashMap<>();  //个人签署方信息
            psnSignerInfo.put("psnAccount",mobile);   // 个人账号标识（手机号或邮箱）

            Map<String, Object> signFieldP = new HashMap<>();  // 签署区信息（设置签署方 盖章/签名/文字输入的区域）
            signFieldP.put("fileId", fileId);    // 签署区所在待签署文件ID
            signFieldP.put("customBizNum", "");  // 开发者自定义业务编号
            Map<String, Object> normalSignFieldConfigP = new HashMap<>(); //签章区配置项
            normalSignFieldConfigP.put("freeMode", false);  // 是否自由签章，默认值 false

            // 页面可选个人印章样式，默认值0和1（英文逗号分隔）0 - 手写签名 1 - 姓名印章 2 - 手写签名AI校验
            normalSignFieldConfigP.put("psnSealStyles", "0");

            normalSignFieldConfigP.put("signFieldStyle", "1");   // 签章区样式  1 - 单页签章，2 - 骑缝签章
            normalSignFieldConfigP.put("movableSignField", false);   //页面是否可移动签章区，默认值 false

            //农户签章的地方关键字
            Map<String, Object> signFieldPositionP = new HashMap<>(); // 签章区位置信息
            if(template.getPositionPage()!=null){
                signFieldPositionP.put("positionX", template.getPositionAcross());   //签章区所在X坐标
                signFieldPositionP.put("positionY", template.getPositionVertical());   //签章区所在Y坐标
                signFieldPositionP.put("positionPage", template.getPositionPage());
            }else{
                List<Map<String, Object>>  posisitony = ESignSignService.getKeywordPositions(fileId, template.getSignKey());
                Map<String, Object> posisitonP = null;
                if(posisitony.size()>0){
                    posisitonP=posisitony.get(0);
                    signFieldPositionP.put("positionX", (float)posisitonP.get("positionX")+100f);   //签章区所在X坐标
                    signFieldPositionP.put("positionY", posisitonP.get("positionY"));   //签章区所在Y坐标
                    signFieldPositionP.put("positionPage", posisitonP.get("pageNum"));
                }
            }
            normalSignFieldConfigP.put("signFieldPosition", signFieldPositionP);
            signFieldP.put("normalSignFieldConfig", normalSignFieldConfigP);
       /*     Map<String, Object> signDateConfigP = new HashMap<>(); //签署日期配置项
            signDateConfigP.put("dateFormat", "yyyy年MM月dd日");  // 日期格式
            signDateConfigP.put("fontSize", 14);  // 日期字体大小
            signDateConfigP.put("showSignDate", 1);  // 是否显示签署日期，默认值0  0.不显示，1.固定位置显示，2.不固定位置
            signDateConfigP.put("signDatePositionX",390f);
            signDateConfigP.put("signDatePositionY", 90f);
            signFieldP.put("signDateConfig", signDateConfigP);*/

            signerP.put("psnSignerInfo", psnSignerInfo);
            List<Map<String, Object>> signFieldsP = new ArrayList<>();
            signFieldsP.add(signFieldP);
            signerP.put("signFields", signFieldsP);

            signers.add(signerP);


            param.put("docs", docs);
            param.put("signFlowConfig", signFlowConfig);
          //  param.put("signFlowInitiator", signFlowInitiator);
            param.put("signers", signers);
            Gson gson = new Gson();
            //请求参数body体,json格式。get或者delete请求时jsonString传空json:"{}"或者null
            String jsonParm = gson.toJson(param);
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>createByFile jsonParam:{}", jsonParm);
            //请求方法
            EsignRequestType requestType = EsignRequestType.POST;
            //生成请求签名鉴权方式的Header
            Map<String, String> header = EsignHttpHelper.signAndBuildSignAndJsonHeader(eSignAppId, eSignAppSecret, jsonParm, requestType.name(), apiaddr, true);
            //发起接口请求
            EsignHttpResponse createByFile = EsignHttpHelper.doCommHttp(eSignHost, apiaddr, requestType, jsonParm, header, true);
            JsonObject createByFileJsonObject = gson.fromJson(createByFile.getBody(), JsonObject.class);
            if (ESignConstants.SUCCESS.equals(createByFileJsonObject.get("code").toString())) {
                JsonObject createByFileData = createByFileJsonObject.getAsJsonObject("data");
                logger.info("====  农户授权信息 发起成功 {}",createByFileData);
                String signFlowId = createByFileData.get("signFlowId").getAsString();   // 签署流程ID
                logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>createAskAuthContract  流程id:" + signFlowId);
                return signFlowId;
            } else {
                logger.error(">>>>>>>>>>>>>>>>>>>>>>>>>>>createAskAuthContract e: " + createByFileJsonObject.get("message"));
                throw new EsignDemoException("发起签署失败!失败原因:" + createByFileJsonObject.get("message"));
            }

        } catch (EsignDemoException e) {
            logger.error("createAskAuthContract 邀请签约获取链接出错=================  {}", e);
            throw new BusinessException(e.getMessage());
        }

    }

    public Map<String,String> getEsignUrl(String idCode,String mobile,String patnerId){
       logger.info(">>>>>getEsignUrl  idCode:{},mobile:{},patnerId:{}",idCode, mobile, patnerId);
        GuardUtils.notBlank(idCode,"身份证号不能为空!");
        GuardUtils.notBlank(mobile,"手机号不能为空!");
        //判断该电站业主预审是否已通过
        Record customerYxCondition = customerDao.findCustomerYxCondition(idCode,patnerId);
        try {
            if(customerYxCondition==null || StringUtil.isBlank(customerYxCondition.getStr("sign_flow_id"))){
                throw new IllegalArgumentException("未找到授权信息");
            }
//            if("3".equals(customerYxCondition.getStr("authorization"))){
//                throw new IllegalArgumentException("已授权，不要重复获取签署链接!");
//            }
            if (!Objects.equals(customerYxCondition.getStr("mobile"),mobile)) {
                throw new BusinessException("800","信息授权合同已发起，手机号与承租人手机号不匹配，需要变更手机号吗？如要变更，重新发起授权！否则请保持手机号为："+customerYxCondition.getStr("mobile"));
            }
            Map<String,String> result=ESignSignService.signUrl(customerYxCondition.getStr("sign_flow_id"),customerYxCondition.getStr("mobile"),"");
            return result;
        } catch (EsignDemoException e) {
            e.printStackTrace();
            throw new IllegalArgumentException(e.getMessage());
        }
    }

    //重新授权（撤销原合同）
    public void resetMobileVsAuth(String idCode, String mobile, String entryId, Operator operator){
        logger.info(">>>>>>>>>resetMobileVsAuth  idCode:{},mobile:{},entryId:{}",idCode,mobile,entryId);
        CustomerEntry entry=customerEntryDao.get(entryId);
        String address=entry.getProvince()+entry.getCity()+entry.getArea()+entry.getAddress();
        Record customerYxCondition = customerDao.findCustomerYxCondition(idCode,entry.getPartnerId());
        //信息使用授权状态：1.未授权 2.已发起 3.已授权
        if(CustomerEntryConstants.AUTHORIZATION_WAIT.equals(customerYxCondition.getStr("authorization"))){
            throw new IllegalArgumentException("未授权，不用重新授权!");
        }
        if(CustomerEntryConstants.AUTHORIZATION_SUCCESS.equals(customerYxCondition.getStr("authorization"))){
            throw new IllegalArgumentException("已授权成功，不用再次授权!");
        }
        try {
            //撤销原合同
            if(StringUtil.isNotBlank(customerYxCondition.getStr("sign_flow_id"))){
                ESignSignService.revoke(customerYxCondition.getStr("sign_flow_id"));
            }
            //重新发起合同
            String signFlowId =createAskAuthContract(idCode,mobile,address,entry.getPartnerId());
            SQLQuery sqlQuery = customerDao.getSession()
                    .createSQLQuery("update crm_customer_yx_condition set mobile=:mobile, authorization='2',sign_flow_id=:signFlowId where id=:id");
            sqlQuery.setParameter("signFlowId", signFlowId);
            sqlQuery.setParameter("mobile",mobile);
            sqlQuery.setParameter("id", customerYxCondition.getStr("id"));
            sqlQuery.executeUpdate();
            Db.update(" UPDATE `crm_customer_entry` SET authorization='2' WHERE  id=?  ",entryId);
            msgService.saveCustomerEntryMsg(operator, entryId, CustomerEntryConstants.AUTH_SIGN, "修改手机号重新发起签约授权 ", "");
        } catch (EsignDemoException e) {
            e.printStackTrace();
            throw new IllegalArgumentException(e.getMessage());
        }
    }

    public static void main(String[] arr) throws IOException {
      String ur= "https://esignoss.esign.cn/1111563786/ff110a34-4283-4fbd-9c59-df9428f07404/%E4%BF%A1%E6%81%AF%E4%BD%BF%E7%94%A8%E6%8E%88%E6%9D%83%E5%8D%8F%E8%AE%AE.pdf?Expires=1698045493&OSSAccessKeyId=LTAI4G23YViiKnxTC28ygQzF&Signature=7SA1kxjHqTwYd8XOIxKa745HyME%3D";
        byte[] fileData=AliyunOSSClientUtil.getFileBytes(ur);
        String fileInfo= AliyunOSSClientUtil.uploadImage(fileData, "pdf","");
        System.out.println(fileInfo);
    }


}
