package weaver.interfaces.htsc.payment;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.engine.htsc.payment.enums.Sequences;
import com.engine.htsc.payment.util.CoWfUtil;
import com.weaver.general.BaseBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import weaver.conn.RecordSet;
import weaver.conn.RecordSetTrans;
import weaver.general.Util;
import weaver.hrm.resource.ResourceComInfo;
import weaver.interfaces.htsc.comInfo.PropBean;
import weaver.interfaces.schedule.BaseCronJob;
import weaver.soa.workflow.request.MainTableInfo;
import weaver.soa.workflow.request.Property;
import weaver.soa.workflow.request.RequestInfo;
import weaver.soa.workflow.request.RequestService;
import weaver.workflow.request.RequestComInfo;
import weaver.workflow.workflow.WorkflowComInfo;
import com.engine.htsc.yfkfyqr.pojo.ReceivingUnitDetail;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class LHAdvancePaymentJob extends BaseCronJob {

    
    private Log log = LogFactory.getLog(this.getClass());


    @Override
    public void execute() {
        PropBean pp = new PropBean();
        String yskmPre = pp.getPropName("LHYFKFYQRaccountTreeId");
        String hjkmPre = pp.getPropName("YFKKJRaccountTreeId");
        log.info("定时任务自动创建流程开始======");
        RecordSetTrans rst = new RecordSetTrans();
        RecordSet rs = new RecordSet();
        RecordSet rsdetail = new RecordSet();
        try{
            rst.setAutoCommit(false);
            PropBean pb = new PropBean();
            //流水号
            int number = -1;
            String workflowId = pb.getPropName("LHYFKQR_WORKFLOWID");
            String tableName = "formtable_main_";
            //获取预付款流程表名
            rs.executeQuery("select formid from workflow_base where id = ?",workflowId);
            if (rs.next()){
                int formid = Math.abs(Util.getIntValue(rs.getString("formid")));
                tableName = tableName + formid;
                log.info("预付款流程表名=="+tableName);
            }else {
                log.info("获取预付款流程表名失败==");
                return;
            }
            String IsNextFlow = "1"; //1提交到下一节点，0不提交
            //1.遍历建模中间表 sfcf 1未触发
            rs.executeQuery("select a.id,a.sqdd,a.biz,a.zzfptjr,a.reqid,a.lcbh,a.ngr,a.bt,a.szbm,a.jjcd,a.jjyy,a.lxfs," +
                    " a.ngsj,a.xjhjmx,a.ngrfyhj,a.fyhjsp,a.ggfyqtfy,a.fkxx,a.fzjgcwjl, " +
                    " (select wm_concat_old(b.skdw) from uf_lhyfkmiddle_dt11 b where a.id = b.mainid) " +
                    " as skdw from uf_lhyfkmiddle a where (a.sfcf = 1 or a.sfcf is null) and a.sffkqr = 1");
            while (rs.next()) {
                log.info("建模存在未触发的数据数据");
                Map<String,String> requestMainMap = new HashMap<String,String>();
                Integer uf_id = Util.getIntValue(rs.getString("id"));
                String requestid = Util.null2String(rs.getString("reqid"));
                String sqdd = Util.null2String(rs.getString("sqdd"));
                log.info("定时任务sqdd:"+sqdd);
                String biz = Util.null2String(rs.getString("biz"));
                log.info("定时任务biz:"+biz);
                String lcbh = Util.null2String(rs.getString("lcbh"));
                String ngr = Util.null2String(rs.getString("ngr"));
                String bt = Util.null2String(rs.getString("bt"));
                String szbm = Util.null2String(rs.getString("szbm"));
                String jjcd = Util.null2String(rs.getString("jjcd"));
                String jjyy = Util.null2String(rs.getString("jjyy"));
                String lxfs = Util.null2String(rs.getString("lxfs"));
                String ngsj = Util.null2String(rs.getString("ngsj"));
                String xjhjmx = Util.null2String(rs.getString("xjhjmx"));
                String ngrfyhj = Util.null2String(rs.getString("ngrfyhj"));
                String fyhjsp = Util.null2String(rs.getString("fyhjsp"));
                String skdw = Util.null2String(rs.getString("skdw"));
                String ggfyqtfy = Util.null2String(rs.getString("ggfyqtfy"));
                String fkxx = Util.null2String(rs.getString("fkxx"));
                String fzjgcwjl = Util.null2String(rs.getString("fzjgcwjl"));
                String zzfptjr = Util.null2String(rs.getString("zzfptjr"));
                String requestName = lcbh + bt + "的预付款费用确认";
                String bz = "收款方： "+skdw + "(已付款挂账)";
                log.info("预付款流程确认标题=="+requestName);



//                预付款流程
                String mark = CoWfUtil.getRequestMarkByUnNumber("lhyfkfyqr", Sequences.NET_REI_WORKFLOW_SEQ_ZB);

                requestMainMap.put("zzfptjr",zzfptjr);
                requestMainMap.put("ngr",ngr);
                requestMainMap.put("sqdd",sqdd);
                requestMainMap.put("biz",biz);
                requestMainMap.put("glyfklc",requestid);
                requestMainMap.put("szbm",szbm);
                requestMainMap.put("jjcd",jjcd);
                requestMainMap.put("jjyy",jjyy);
                requestMainMap.put("lxfs",lxfs);
                requestMainMap.put("ngsj",ngsj);
                requestMainMap.put("xjhjmx",xjhjmx);
                requestMainMap.put("ngrfyhj",ngrfyhj);
                requestMainMap.put("fyhjsp",fyhjsp);
                requestMainMap.put("ggfyqtfy",ggfyqtfy);
                requestMainMap.put("bz",bz);
                requestMainMap.put("spjg","0");
                requestMainMap.put("fkxx",fkxx);
                requestMainMap.put("fzjgcwjl",fzjgcwjl);
                requestMainMap.put("lcbh",mark.toString());
                requestMainMap = removeNullValue(requestMainMap);
                log.info("预付款流程生成过滤后参数=="+ JSON.toJSONString(requestMainMap));
                //2.自动创建流程获取requestid
                int requestid_main_213 = Util.getIntValue(WorkflowCreateByRequestMap(ngr,workflowId,requestName,IsNextFlow,requestMainMap));
                log.info("预付款流程确认自动生成requestid=="+requestid_main_213);
                if (requestid_main_213 > 0) {
                    Integer form_id = null;
                    rsdetail.executeQuery("select id from "+tableName+" where requestid = ?",requestid_main_213);
                    if (rsdetail.next()){
                        form_id = Util.getIntValue(rsdetail.getString("id"));
                    }

                    //1.更新流程编号
                    log.info("requestid=="+requestid_main_213+"==lcbh:"+mark.toString());
                    rst.executeUpdate("update workflow_requestbase set requestmark = ? where requestid = ? ",mark.toString(),requestid_main_213);


                    //3.更新预付款流程的明细表（采用批量插入更新方法）只执行一次
                    String tableName_detail_eight = tableName + "_dt8";
                    String detail_eight_sql = "insert into "+tableName_detail_eight+" (mainid,sftxxm,gsxm,xmszbm,ysxm,ysxmbm,bhsje,sj,jshjje,sy,fysjcdbm,sl,yskm,slz,htbh,cys,yskmid) " +
                            " select  "+form_id+",sftxxm,gsxm,xmssbm,ysxm,ysxmbm,bhsje,sj,jshjje,sy,fysjcdbm,sl,yskm,slz,htbh,cys,'"+yskmPre+"_'||yskm from uf_lhyfkmiddle_dt8 where mainid = "+uf_id+"";
                    log.info("批量插入sql明细表8=="+detail_eight_sql);
                    rst.executeUpdate(detail_eight_sql);

                    String tableName_detail_nine = tableName + "_dt9";
                    String detail_nine_sql = "insert into "+tableName_detail_nine+" (mainid,rmbje,htbh,sy,bz,hl,wbje,yskm,fysjcdbm,cys,yskmid) " +
                            " select  "+form_id+",rmbje,htbh,sy,bz,hl,wbje,yskm,fysjcdbm,cys,'"+yskmPre+"_'||yskm from uf_lhyfkmiddle_dt9 where mainid = "+uf_id+"";
                    log.info("批量插入sql明细表9=="+detail_nine_sql);
                    rst.executeUpdate(detail_nine_sql);

                    String tableName_detail_eleven = tableName + "_dt11";
                    String detail_eleven_sql = "insert into "+tableName_detail_eleven+" (mainid,skdw,yxzh,khx,ss,yxzfje,xjzfje,dfkje,lsjl,khxmc) " +
                            " select  "+form_id+",skdw,yxzh,khx,ss,yxzfje,xjzfje,dfkje,lsjl,khxmc from uf_lhyfkmiddle_dt11 where mainid = "+uf_id+"";
                    log.info("批量插入sql明细表11=="+detail_eleven_sql);
                    rst.executeUpdate(detail_eleven_sql);

                    String tableName_detail_twelve = tableName + "_dt12";
                    String detail_twelve_sql = "insert into "+tableName_detail_twelve+" (mainid,fysjcdbm,je,sjbz,zhrmb,hjkm,hl,hjkmid,yskmmc,yskm) " +
                            " select "+form_id+",fysjcdbm,je,sjbz,zhrmb,hjkm,hl,'"+hjkmPre+"_'||hjkm,yskmmc,yskm from uf_lhyfkmiddle_dt12 where mainid = "+uf_id+"";
                    log.info("批量插入sql明细表12=="+detail_twelve_sql);
                    rst.executeUpdate(detail_twelve_sql);

                    // 对比详情明细表数据插入
                    List<ReceivingUnitDetail> receivingUnitDetails = updateDt13(requestid, tableName + "_13");
                    log.info("需要插入的数据是：" + receivingUnitDetails);
                    for (ReceivingUnitDetail unitDetail : receivingUnitDetails) {
                        String skdw1 = unitDetail.getSkdw();
                        String yfkje = unitDetail.getYfkje();
                        String yhxje = unitDetail.getYhxje();
                        String dhxje = unitDetail.getDhxje();
                        String insertSql = "insert into "+tableName + "_dt13"+"(mainid,skdw,yfkje,yhxje,dhxje) " +
                                "values('"+form_id+"','"+skdw1+"','"+yfkje+"','"+yhxje+"','"+dhxje+"')";
                        log.info("即将执行insert dt13的语句是：" + insertSql);
                        rst.executeUpdate(insertSql);
                    }



                    //4.更新建模中间表表示该条数据已完成新建流程
                    rst.executeUpdate("update uf_lhyfkmiddle set sfcf = 0 where reqid = ?",requestid);
                    log.info("AdvancePaymentJob==预付款流程自动创建成功==");


                }
            }
            log.info("==建模中间表未存在需要自动触发的流程===");
            rst.commit();
        }catch (Exception e){
            rst.rollback();
            log.info("预付款流程自动创建失败");
            e.printStackTrace();
        }

    }

    /**
     * 根据requestid获取原付款流程的支付明细信息
     *
     * @param requestid 原付款流程reqquestid
     * @return
     */
    private List<ReceivingUnitDetail> getPaymentWorkFlowReceiveDetail(String requestid) {
        log.info("开始获取原付款流程支付明细信息，接收到的requestid是：" + requestid);
        List<ReceivingUnitDetail> receivingPayUnitDetails = new ArrayList<>();
        RecordSet rs = new RecordSet();
        String sql;
        String mainTable = "";
        sql = "select t2.tablename from workflow_requestbase t0,workflow_base t1,workflow_bill t2 where t0.workflowid = t1.id and t1.formid = t2.id and  t0.requestid = ?";
        log.info("即将执行的sql是：" + sql);
        rs.executeQuery(sql, requestid);
        if (rs.next()) {
            mainTable = Util.null2String(rs.getString("tablename"));
        }
        if (!"".equals(mainTable)) {
            sql = "select SKDW,DFKJE from " + mainTable + "_dt11 where mainid = (select id from " + mainTable + " where requestid = '" + requestid + "')";
            log.info("即将执行的sql语句是：" + sql);
            rs.executeQuery(sql);
            while (rs.next()) {
                boolean isNew = true;
                String skdw = Util.null2String(rs.getString("SKDW"));
                log.info("开始操作的收款单位是：" + skdw);
                String dfkje = Util.null2String(rs.getString("DFKJE"));
                log.info("开始操作的待付款金额是：" + dfkje);
                log.info("目前收集到的原付款支付信息是：" + JSONObject.toJSONString(receivingPayUnitDetails));
                for (ReceivingUnitDetail receivingPayUnitDetail : receivingPayUnitDetails) {
                    if (receivingPayUnitDetail.getSkdw().equals(skdw)) {
                        isNew = false;
                        receivingPayUnitDetail.setYfkje(String.valueOf(str2double(dfkje) + str2double(receivingPayUnitDetail.getYfkje())));
                    }
                }
                if (isNew) {
                    ReceivingUnitDetail unitDetail = new ReceivingUnitDetail();
                    unitDetail.setSkdw(skdw);
                    unitDetail.setYfkje(dfkje);
                    receivingPayUnitDetails.add(unitDetail);
                }
            }
        }
        return receivingPayUnitDetails;
    }

    /**
     * 获取所有关联此付款流程并且已办结的预付款费用确认流程，并且取发票中的销方名称以及对应的加税合计金额
     * 1、考虑预付款费用确认流程中发票明细表为5、6两张表
     * 2、考虑可能存在销方名称一样的发票
     *
     * @param requestid 原付款流程
     * @return
     */
    private Map<String, Double> getPrepaymentWfReceiveDetail(String requestid) {
        log.info("=-=-=-=-=-=-=-=-=-=-=进入获取所有关联此付款流程并且已办结的预付款收据收集方法=-=-=-=-=-=-=-=-=-=-=");
        PropBean pp = new PropBean();
        String yfkMainTable = pp.getPropName("yfkTableName");
        log.info("获取的预付款流程主表名是：" + yfkMainTable);
        return getInvoiceDetail(yfkMainTable, "5,6", requestid);
    }

    /**
     * 获取指定原付款流程并且已办结的预付款流程发票销方名称以及对应的价税合计金额
     *
     * @param yfkMainTable 预付款流程主表名
     * @param dtNums       对应明细表,多个时以英文逗号分隔
     * @param requestid    原付款流程的requestid
     * @return Map<String, Object>
     */
    private Map<String, Double> getInvoiceDetail(String yfkMainTable, String dtNums, String requestid) {
        log.info("-=-=-=-=-=-=-=-=-=-=获取预付款流程发票销方名称以及对应的价税合计金额方法，原付款流程requestid为：" + requestid);
        Map<String, Double> invoiceDetail = new HashMap<>();
        RecordSet rs = new RecordSet();
        String sql = "";
        for (String dtNum : dtNums.split(",")) {
            if ("5".equals(dtNum)) {
                sql = "select currentnodetype,isstopped,XFMC,JSHJ from " + yfkMainTable + " a," +
                        "workflow_requestbase b," + yfkMainTable + "_dt5 c where a.requestid = b.requestid and a.id = c.mainid and a.GLYFKLC = '" + requestid + "'";
                log.info("即将执行的sql是：" + sql);
                rs.executeQuery(sql);
                while (rs.next()) {
                    String currentnodetype = Util.null2String(rs.getString("currentnodetype"));
                    String isstopped = Util.null2String(rs.getString("isstopped"));
                    if ((!"1".equals(isstopped)) && ("3".equals(currentnodetype))) {
                        String xfmc = "".equals(Util.null2String(rs.getString("XFMC"))) ? "空" : Util.null2String(rs.getString("XFMC"));
                        String jshj = Util.null2String(rs.getString("JSHJ"));
                        if (invoiceDetail.containsKey(xfmc)) {
                            Double oldJshj = invoiceDetail.get(xfmc);
                            invoiceDetail.put(xfmc, oldJshj + str2double(jshj));
                        } else {
                            invoiceDetail.put(xfmc, str2double(jshj));
                        }
                    }
                }
            }
            if ("6".equals(dtNum)) {
                sql = "select currentnodetype,isstopped,kpf,kpje from " + yfkMainTable + " a," +
                        "workflow_requestbase b," + yfkMainTable + "_dt6 c where a.requestid = b.requestid and a.id = c.mainid and a.GLYFKLC = '" + requestid + "'";
                log.info("即将执行的sql是：" + sql);
                rs.executeQuery(sql);
                while (rs.next()) {
                    String currentnodetype = Util.null2String(rs.getString("currentnodetype"));
                    String isstopped = Util.null2String(rs.getString("isstopped"));
                    if ((!"1".equals(isstopped)) && ("3".equals(currentnodetype))) {
                        String xfmc = "".equals(Util.null2String(rs.getString("kpf"))) ? "空" : Util.null2String(rs.getString("kpf"));
                        String jshj = Util.null2String(rs.getString("kpje"));
                        if (invoiceDetail.containsKey(xfmc)) {
                            Double oldJshj = invoiceDetail.get(xfmc);
                            invoiceDetail.put(xfmc, oldJshj + str2double(jshj));
                        } else {
                            invoiceDetail.put(xfmc, str2double(jshj));
                        }
                    }
                }
            }
        }
        return invoiceDetail;
    }

    /**
     * 对比详情明细表数据插入
     * @param requestid 原付款流程的requestid
     * @param dtTableName 预付款费用确认流程对比详情明细表名
     */
    private List<ReceivingUnitDetail> updateDt13(String requestid, String dtTableName) {
//        1、取原付款流程的支付模块信息
        List<ReceivingUnitDetail> receivingUnitDetails = getPaymentWorkFlowReceiveDetail(requestid);
//        2、取关联此付款流程并且已经办结的预付款费用确认流程票据信息
        Map<String, Double> prepaymentUnitDetail = getPrepaymentWfReceiveDetail(requestid);
//        3、数据合并返回
//            3.1、匹配的数据整理
        for (ReceivingUnitDetail receivingUnitDetail : receivingUnitDetails) {
            String skdw = receivingUnitDetail.getSkdw();
            if (prepaymentUnitDetail.containsKey(skdw)) {
                receivingUnitDetail.setYhxje(prepaymentUnitDetail.get(skdw).toString());
                receivingUnitDetail.setDhxje(String.valueOf(str2double(receivingUnitDetail.getYfkje()) - prepaymentUnitDetail.get(skdw)));
            } else {
                receivingUnitDetail.setYhxje("0.00");
                receivingUnitDetail.setDhxje(receivingUnitDetail.getYfkje());
            }
        }
//        3.2、未匹配数据整理
        List<ReceivingUnitDetail> unCheckedList = new ArrayList<>();
        for (String skdw : prepaymentUnitDetail.keySet()) {
            boolean isHas = true;
            for (ReceivingUnitDetail receivingUnitDetail : receivingUnitDetails) {
                if (!receivingUnitDetail.getSkdw().equals(skdw)){
                    isHas = false;
                }
            }
            if (!isHas){
                ReceivingUnitDetail unChecked = new ReceivingUnitDetail();
                unChecked.setSkdw(skdw);
                unChecked.setYfkje("0.00");
                unChecked.setYhxje(Util.null2String(prepaymentUnitDetail.get(skdw)));
                unChecked.setDhxje("0.00");
                unCheckedList.add(unChecked);
            }
        }
        if (unCheckedList.size()!=0){
//                将没有校验上的数据添加到前端返回数组中
            receivingUnitDetails.addAll(unCheckedList);
        }
        return receivingUnitDetails;
    }


    /**
     * 数字的字符串转double类型
     *
     * @param str
     * @return
     */
    private static double str2double(String str) {
        str = "".equals(str) ? "0" : str;
        double num;
        DecimalFormat myformat = new DecimalFormat("#0.00");
        //装换为double类型
        num = Double.parseDouble(str);
        //保留2为小数
        num = Double.parseDouble(myformat.format(num));
        return num;
    }





    /**
     * 移除map中的空值数据
     * @param map
     * @return
     */
    public static Map<String,String> removeNullValue(Map<String,String> map){
        Map<String,String> newMap = new HashMap<String,String>();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            if(value!=null && !"".equals(value)){
                newMap.put(key,value);
            }
        }
        return newMap;
    }


    /**
     *
     * @Title: 自动创建流程
     * @param @param creatorId    创建人Id
     * @param @param workflowId   流程Id
     * @param @param requestName  请求标题
     * @param @param IsNextFlow   是否提交到下一节点
     * @param @param requestMap   Map格式的主表数据<fieldname,fieldvalue>=<字段名称,字段值>
     * @param @return    设定文件
     * @return String    返回类型
     * @throws
     */
    public static String WorkflowCreateByRequestMap(String creatorId,String workflowId,
                                                    String requestName,String IsNextFlow,
                                                    Map<String,String> requestMainMap) {
        BaseBean bs = new BaseBean();
        String requestid = "";
        RequestInfo requestInfo = new RequestInfo();
        requestInfo.setCreatorid(creatorId);//创建人Id
        requestInfo.setWorkflowid(workflowId);//工作流Id
        requestInfo.setDescription(requestName);//请求标题
        if(!"".equals(IsNextFlow))
        {
            requestInfo.setIsNextFlow(IsNextFlow);
        }
        //主表字段
        MainTableInfo mainTableInfo = new MainTableInfo();
        Property[] propertyArray = new Property[requestMainMap.size()];
        int p = 0;
        for (Map.Entry<String, String> entry : requestMainMap.entrySet())
        {
            propertyArray[p] = new Property();
            propertyArray[p].setName(Util.null2String(entry.getKey()));
            propertyArray[p].setValue(Util.null2String(entry.getValue()));
            bs.writeLog("\r\n---p="+p+"---Key="+entry.getKey()+"---Value="+entry.getValue());
            p++;
        }
        bs.writeLog("-----创建流程传递的参数个数p="+p);
        mainTableInfo.setProperty(propertyArray);
        requestInfo.setMainTableInfo(mainTableInfo);
        RequestService service = new RequestService();
        try {
            //流程
            try {
                requestid = service.createRequest(requestInfo);//创建请求id
            } catch (Exception e) {
                bs.writeLog("预付款流程触发异常"+e.getMessage());
            }
            //String userId = requestInfo.getLastoperator();//请求最后的操作者
            //记录日志
            StringBuffer sbf = new StringBuffer("\r\n-----xwd创建工作流记录日志开始");
            WorkflowComInfo wfcif =new WorkflowComInfo();
            RequestComInfo rcif = new RequestComInfo();
            ResourceComInfo rscif = new ResourceComInfo();
            sbf.append("\r\n-----姓名:"+rscif.getLastname(rcif.getRequestCreater(requestid)));
            sbf.append("\r\n-----时间:"+rcif.getRequestCreateTime(requestid));
            sbf.append("\r\n-----创建流程:"+wfcif.getWorkflowname(workflowId));
            sbf.append("\r\n-----请求:"+rcif.getRequestname(requestid));
            sbf.append("\r\n-----请求:"+requestid);
            sbf.append("\r\n-----创建工作流记录日志结束");
            bs.writeLog(sbf.toString());
            System.out.println(""+sbf.toString());
        } catch (Exception e) {
            bs.writeLog("错误：" + e);
            System.out.println("错误：" + e);
        }
        return requestid;
    }

}
