package com.engine.htxc.eseal.responseaction.business.contract.service;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.engine.htsc.seal.web.RedisTools;
import com.engine.htxc.commonutil.db.DbTools;
import com.engine.htxc.commonutil.log.CustomizeLog;
import com.engine.htxc.eseal.responseaction.coninterface.EsealResponseInterface;
import com.engine.htxc.eseal.responseaction.num.EsealTypeEnum;
import com.engine.htxc.eseal.responseaction.util.EsealPesUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import redis.clients.jedis.Jedis;
import weaver.general.Util;
import weaver.interfaces.htsc.GlobatTools.MessageDetailLog;
import weaver.interfaces.htsc.comInfo.PropBean;
import com.engine.htxc.eseal.responseaction.num.FileSignsStatusEnum;
import static com.engine.htxc.eseal.responseaction.num.SignsStatusEnum.Completed;


import java.util.*;
import java.util.stream.Collectors;

/**
 * @author K1810015
 * @version 1.0.0
 * @ClassName EsealContractReq.java
 * @createTime 2022年06月28日 00:40:00
 */
@Slf4j
public class EsealContractReq extends EsealPesUtil implements EsealResponseInterface {

    /**
     * 特殊情况，同事返回RXF和pdf
     */
    public String systemdas="DAS";

    public EsealContractReq(String tablename){
        super(tablename);
        if (systemdas.equals(tablename)){
            reponseSealConfig.securityautopdf=true;
        }
    }
    public PropBean pb = new PropBean();
    Map<String,Object> mainmap=new HashMap<>();
    private DbTools dbtools=new DbTools();
    public FileSignsStatusEnum fileSignsStatusEnum;
    public EsealTypeEnum esealTypeEnum;
    public boolean flag=true;
    public JSONObject retmes=new JSONObject();

    public JSONObject mainjson=new JSONObject();

    @Override
    public JSONObject receivestatus(JSONObject jsonObject) {
        String flowNum = jsonObject.getString("flowNum");
        if(StringUtils.isBlank(flowNum)){
            retmes.put("resultMsg","参数有误");
            retmes.put("status", "-1");
            return retmes;
        }
        initload(flowNum);
         if(StringUtils.isBlank(this.id)){
            retmes.put("resultMsg","异常");
            retmes.put("status", "-1");
            return retmes;
        }
        mainjson=jsonObject;
        CustomizeLog.printLog("receiveSeal start:"+id);
        String manualSigndoctype = pb.getPropName("eseal.contract.doctype");
        try{

            MessageDetailLog messageDetailLog = new MessageDetailLog(tablename);
            String docSigns = jsonObject.getString("docSigns");
            JSONArray docSignsArray = JSONArray.parseArray(docSigns);
            for(int i=0;i<docSignsArray.size();i++){
                JSONObject docSignObject = (JSONObject)docSignsArray.get(i);
                String status = docSignObject.get("status").toString();
                fileSignsStatusEnum=FileSignsStatusEnum.where(status);
                String signers = docSignObject.get("signers").toString();
                String docid =docSignObject.get("docId").toString();
                getdetailid(docid);
                if(this.detailtable.indexOf("_dt3")>0){
                    this.mainsignfieldname="htfjdzyyj";
                }
                if(StringUtils.isBlank(this.detailtable)){
                    retmes.put("resultMsg","明细表异常");
                    retmes.put("status", "-1");
                    return retmes;
                }
                String dzyyfs=Util.null2String(this.detailmap.get("dzyyfs"));
                esealTypeEnum=EsealTypeEnum.where(dzyyfs);
                String docType = docSignObject.get("docType").toString();
                if(manualSigndoctype.equals(docType)){
                    boolean signersFlag = true;
                    JSONArray signersArray = JSONArray.parseArray(signers);
                    for(int j=0;j<signersArray.size();j++){
                        JSONObject signObject = (JSONObject)signersArray.get(i);
                        String signStatus = signObject.get("status").toString();
                        if("7".equals(signStatus)){
                            //签署失败
                            signersFlag = false;
                        }
                        signnext(docSignObject,signersArray);
                    }
                    if(!signersFlag){
                        updateSignStatus("4","");
                        messageDetailLog.writLogsnotretrun(id,jsonObject.toJSONString(),"2",messageDetailLog.fail);
                        return null;
                    }

                }
                if(!flag){
                    return retmes;
                }else {
                    retmes.put("data", "签署文件保存成功");
                    retmes.put("status", "200");
                }
            }
        }catch (Exception e){
            retmes.put("resultMsg","异常");
            retmes.put("status", "-1");
        }
        CustomizeLog.printLog("receiveSeal end:"+id);
        return retmes;
    }

    public void signnext(JSONObject docSignObject,JSONArray signersArray){
        switch (fileSignsStatusEnum) {
            case Starting:
                if(esealTypeEnum==EsealTypeEnum.Online) {
                    onlineStarting(docSignObject, signersArray);
                }
                //进行中操作
                break;
            case Completed:
                messageDetailLog.writLogsnotretrun(id,mainjson.toJSONString(),"2",messageDetailLog.success);
                save(docSignObject,signersArray);
                //已完成
                break;
            case Refuse:
                updateSignStatus("5","");
                messageDetailLog.writLogsnotretrun(id,mainjson.toJSONString(),"2",messageDetailLog.refuse);
                break;

            case WatermarkSucess:
                messageDetailLog.writLogsnotretrun(id,mainjson.toJSONString(),"2",messageDetailLog.watermark);
                break;
            case WatermarkRefuse:
                updateSignStatus("4","");
                messageDetailLog.writLogsnotretrun(id,mainjson.toJSONString(),"2",messageDetailLog.fail);
                break;
            default:
                messageDetailLog.writLogsnotretrun(id,mainjson.toJSONString(),"2",messageDetailLog.Other);
                break;
        }
    }

    /**
     * <p>保存用印成功的文件</p>
     * @title save
     * @author K1810015
     * @updateTime 2022/8/3 11:32
     * @throws
     */
    private void save(JSONObject docSignObject,JSONArray signersArray){
        try{
            int newdocid=saveFileid(docSignObject,esealTypeEnum);
             if(newdocid<0){
                CustomizeLog.printLog("newdocid没有获取到:"+newdocid);
                retmes.put("resultMsg","参数有误");
                retmes.put("status", "400");
                this.flag=false;
                return ;
            }
            updateSignStatus("3",String.valueOf(newdocid));
            signdate(signersArray);
            dosavemain(newdocid);
        }catch (Exception e){
            CustomizeLog.printLog(e.getMessage());
            this.flag=false;
            retmes.put("resultMsg","异常");
            retmes.put("status", "-1");
        }
    }

    private void dosavemain(int newdocid){
        Jedis jedis = RedisTools.GetJedis();
        String rediskey = tablename+"_redis_key";
        try{
            int expireTime= Util.getIntValue(Util.null2String(pb.getPropName("RedisExpiretime")));
            boolean redisfalg=RedisTools.getDistributedLock(jedis,rediskey,id,expireTime,500,10);
            if(redisfalg){
                updateMainTable(String.valueOf(newdocid));
            }
        }catch (Exception e){
            log.error(rediskey+"保存失败"+e.getMessage());
        }finally {
            log.info(rediskey+"解锁开始");
            RedisTools.releaseDistributedLock(jedis,rediskey,id);
            log.info(rediskey+"解锁结束");
            log.info(rediskey+"释放锁开始");
            jedis.close();
            log.info (rediskey+"释放锁结束");
        }
    }


    /**
     * <p>在先用印成功的文件</p>
     * @title onlinesave
     * @author K1810015
     * @updateTime 2022/8/3 11:32
     * @throws
     */
    private void onlineStarting(JSONObject docSignObject,JSONArray signersArray){
        if(detailmap==null || detailmap.size()<=0){
            return ;
        }
        String wfqssj=Util.null2String(detailmap.get("wfqssj"));
        String qszt=Util.null2String(detailmap.get("qszt"));
        if(!StringUtils.isBlank(wfqssj) && !StringUtils.isBlank(qszt)){
            return;
        }
        signersArray.stream().forEach(item->{
            JSONObject obj=(JSONObject) item;
            if(obj!=null && obj.size()>0){
               String code= Util.null2String(obj.get("code"));
               if(!StringUtils.isBlank(code) &&!StringUtils.isBlank(yzcode)){
                   if(Arrays.stream(code.split(",")).collect(Collectors.toList()).removeAll(
                           Arrays.stream(yzcode.split(",")).collect(Collectors.toList())
                   )){
                   //修改我方签署时间
                   String docstatus= Util.null2String(obj.get("status"));
                   int newdocid=saveFileid(docSignObject,esealTypeEnum);
                   if(!StringUtils.isBlank(docstatus) &&docstatus.equals(Completed.getValue())){
                       String signTime =Util.null2String(obj.get("signTime"));
                       if(!StringUtils.isBlank(signTime)){
                           Map<String,String> wheremap=new HashMap<>(2);
                           wheremap.put("wfqssj",signTime);
                           wheremap.put("qszt","1");
                           if(newdocid>0){
                               wheremap.put("wfyyj",Util.null2String(newdocid));
                           }
                           updatiltable(wheremap);
                           updateSignStatus("2",String.valueOf(newdocid));
                           dosavemain(newdocid);
                       }

                   }
               }
            }
        }
    });
    }

    private void initload(String flownum){
        if(StringUtils.isBlank(flownum)){
            return ;
        }
        String sql="select * from "+this.tablename+" where 1=1 ";
        Map<String,String> wheremap=new HashMap<>(1);
        wheremap.put("htbh",flownum);
        Map<String,Object> retmap=dbtools.gettabletomap(this.tablename,wheremap);
        if(retmap==null || retmap.size()<=0){
            return ;
        }
        mainmap=retmap;
        this.id=Util.null2String(retmap.get("id"));
        this.yzcode=Util.null2String(pb.getPropName("AutoSign.code"));
    }

    private void signdate(JSONArray signersArray){
        List<DateTime> datelist=new ArrayList<>();
        signersArray.stream().forEach(item->{
        JSONObject obj=(JSONObject) item;
        if(obj!=null && obj.size()>0){
            //修改我方签署时间
            String docstatus= Util.null2String(obj.get("status"));
            if(!StringUtils.isBlank(docstatus) &&docstatus.equals(Completed.getValue())){
                String signTime =Util.null2String(obj.get("signTime"));
                if(!StringUtils.isBlank(signTime)){
                    datelist.add(DateUtil.parse(signTime));
                }
            }
        }
    });
    if(datelist==null || datelist.size()<0){
        return ;
    }
   datelist.sort(Comparator.comparing(DateTime::getTime));
   String datetime= ((DateTime)datelist.get(datelist.size()-1)).toString("yyyy-MM-dd HH:mm:ss");
        Map<String,String> wheremap=new HashMap<>(2);
        wheremap.put("sfqssj",datetime);
        wheremap.put("qszt","2");
        updatiltable(wheremap);
    }


}