package com.engine.htsc.yfkfyqr.dao;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.engine.common.biz.AbstractCommonCommand;
import com.engine.common.entity.BizLogContext;
import com.engine.core.interceptor.CommandContext;
import com.engine.htsc.payment.enums.Sequences;
import com.engine.htsc.payment.util.CoWfUtil;
import com.weaver.general.BaseBean;
import org.apache.commons.lang3.StringUtils;
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.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.logging.Logger;
import weaver.workflow.logging.LoggerFactory;
import weaver.workflow.request.RequestComInfo;
import weaver.workflow.workflow.WorkflowComInfo;

import java.text.MessageFormat;
import java.util.*;

public class ManualPrepaymentsCMD extends AbstractCommonCommand<Map<String, Object>> {
    Logger logger = LoggerFactory.getLogger(ManualPrepaymentsCMD.class);


    @Override
    public BizLogContext getLogContext() {
        return null;
    }

    public ManualPrepaymentsCMD(Map<String, Object> params) {
        this.params = params;
    }

    @Override
    public Map<String, Object> execute(CommandContext commandContext) {
        /**
         * 返回的数据格式：
         * ｛
         *      isSuccess:boolean,
         *      successMes:string,
         *      errorMes:string,
         * ｝
         */
        Map<String, Object> result = new HashMap<>();
        String[] requestIds = Util.null2String(params.get("requestIds")).split(",");
        String yfkTableName = Util.null2String(params.get("yfkTableName"));
        logger.info("获取到的requestids是：" + JSONObject.toJSONString(requestIds) + ",预付款主表名是：" + yfkTableName);
        if (requestIds.length == 0 || "".equals(StringUtils.join(requestIds, ","))) {
            result.put("isSuccess", "false");
            result.put("successMes", "");
            result.put("errorMes", "requestIds为空，请联系管理员处理");
        } else {
            boolean isSuccess = true;
            String successMes = "";
            String errorMes = "";
            // 1、检验要触发付款的流程是否存在未办结的预付款费用确认流程
            Map<String, List<String>> fixResult = isFinished(requestIds, yfkTableName);
            List<String> noFinished = fixResult.get("error");
            List<String> pass = fixResult.get("pass");
            if (noFinished.size() != 0) {
                logger.info("存在已发起预付款流程编写未办结的付款流程编号是：" + StringUtils.join(noFinished, ","));
                isSuccess = false;
                errorMes += StringUtils.join(noFinished, ",");
            }
            if (pass.size() != 0) {
                // 2、触发满足条件的付款流程的预付款流程
                logger.info("这些付款流程的requestid不存在未办结的预付款费用确认流程" + JSONObject.toJSONString(pass) + "即将被触发");
                // 3、触发原付款流程的预付款费用确认流程
                for (String requestidAndLcbh : pass) {
                    logger.info("当前准备触发的原付款流程是：" + requestidAndLcbh);
                    Map<String, Object> workflow = createAdvanceWorkflow(requestidAndLcbh);
                    logger.info("触发的结果是:" + JSONObject.toJSONString(workflow));
                    if ((boolean) workflow.get("isSuccess")) {

                    } else {
                        isSuccess = false;
                    }
                    if ("".equals(successMes)) {
                        successMes += workflow.get("successMes");
                    } else {
                        successMes += "，" + workflow.get("successMes");
                    }

                    errorMes += workflow.get("errorMes");
                }
            }
            result.put("isSuccess", isSuccess ? "true" : "false");
            result.put("successMes", successMes);
            result.put("errorMes", errorMes);
        }

        return result;
    }

    private List<List<String>> dataIsWhole(String[] requestIds) {
        List<List<String>> data = new ArrayList<>();
        List<String> ok = new ArrayList<>();
        List<String> error = new ArrayList<>();
        RecordSet rs = new RecordSet();
        String sql = "select requtid,lclx,lczbm from uf_PrepayMageAccRep where requtid in (" + StringUtils.join(requestIds, ",") + ")";
        rs.executeQuery(sql, StringUtils.join(requestIds, ","));
        while (rs.next()) {
            if ("".equals(Util.null2String(rs.getString("lclx"))) || "".equals(Util.null2String(rs.getString("lczbm")))) {
                error.add(Util.null2String(rs.getString("requtid")));
            } else {
                ok.add(Util.null2String(rs.getString("requtid")));
            }
        }
        data.add(error);
        data.add(ok);
        return data;
    }

    /**
     * 批量处理，根据付款流程的requestId，到预付款费用确认流程中查找是否有已经发起并且没有办结的付款流程
     */
    private Map<String, List<String>> isFinished(String[] requestIds, String yfkTableName) {
        RecordSet rs = new RecordSet();
        String sql = "";
        List<String> pass = new ArrayList<>();
        List<String> error = new ArrayList<>();
        Map<String, List<String>> dealResult = new HashMap<>();
        for (String requestId : requestIds) {
            sql = "select currentnodetype,isstopped,lcbh,status " +
                    ",(select t1.tablename from workflow_bill t1,workflow_base t2,workflow_requestbase t3 where t1.id =t2.formid and t2.id = t3.workflowid and t3.requestid = '" + requestId + "') as mainTable" +
                    " from workflow_requestbase a join " + yfkTableName + " b on a.requestid = b.requestid where a.requestid in (select requestid from " + yfkTableName + " where GLYFKLC = '" + requestId + "')";
            rs.executeQuery(sql);
            boolean isOK = true;
            while (rs.next()) {
                String isstopped = Util.null2String(rs.getString("isstopped"));
                String currentnodetype = Util.null2String(rs.getString("currentnodetype"));
                String lcbh = Util.null2String(rs.getString("lcbh"));
                String status = Util.null2String(rs.getString("status"));
                if ((!"1".equals(isstopped)) && ("3".equals(currentnodetype))) {
                } else {
                    isOK = false;
                    error.add("预付款确认流程（" + lcbh + "）正在进行中，请办结后再触发新的费用确认流程");
                }
            }
            if (isOK) {
                String requestIdAndLcbh = requestId + "&" + getLcbhByRequestId(getMainTable(requestId), requestId);
                pass.add(requestIdAndLcbh);
            }
        }
        dealResult.put("pass", pass);
        dealResult.put("error", error);
        return dealResult;
    }

    private String getMainTable(String requestId) {
        RecordSet rs = new RecordSet();
        rs.executeQuery("select t1.tablename from workflow_bill t1,workflow_base t2,workflow_requestbase t3 where t1.id =t2.formid and t2.id = t3.workflowid and t3.requestid = '" + requestId + "'");
        if (rs.next()) {
            return Util.null2String(rs.getString("tablename"));
        } else {
            return null;
        }
    }

    private String getLcbhByRequestId(String mainTable, String requestid) {
        RecordSet rs = new RecordSet();
        rs.executeQuery("select lcbh from " + mainTable + " where requestid = '" + requestid + "'");
        if (rs.next()) {
            return Util.null2String(rs.getString("lcbh"));
        } else {
            return "";
        }

    }

    /**
     * 根据付款流程的requestId批量触发预付款流程
     *
     * @param requestidAndLcbh 付款流程requestid
     * @return 创建结果
     * 返回值样式
     * ｛
     * isSuccess:boolean,
     * successMes:string,
     * errorMes:string
     * ｝
     */
    private Map<String, Object> createAdvanceWorkflow(String requestidAndLcbh) {
        PropBean pp = new PropBean();
        Map<String, Object> result = new HashMap<>();
        String yskmPre = pp.getPropName("YFKFYQRaccountTreeId");
        String hjkmPre = pp.getPropName("YFKKJRaccountTreeId");
        logger.info("触发预付款费用确认流程开始======requestIds：" + requestidAndLcbh);
        RecordSetTrans rst = new RecordSetTrans();
        RecordSet rs = new RecordSet();
        RecordSet rsdetail = new RecordSet();
        List<String> createSuccess = new ArrayList<>();
        try {
            rst.setAutoCommit(false);
            //流水号
            int number = -1;
            String workflowId = pp.getPropName("YFKQR_WORKFLOWID");
            String tableName = pp.getPropName("yfkTableName");
            //1提交到下一节点，0不提交
            String IsNextFlow = "1";
//            for (String requestidAndLcbh : requestidAndLcbhs) {
            Map<String, String> selectSqlAndMainTable = getSelectSql(requestidAndLcbh);
            logger.info("付款流程的查询SQL和主表名：" + selectSqlAndMainTable);
            String selectSql = Util.null2String(selectSqlAndMainTable.get("sql"));
            logger.info("即将执行的主数据获取SQL是：" + selectSql);
            String mainTable = Util.null2String(selectSqlAndMainTable.get("mainTable"));
            logger.info("该预付款的主表名是：" + mainTable);
            rs.executeQuery(selectSql);
            while (rs.next()) {
                Map<String, String> requestMainMap = new HashMap<String, String>();
                Integer uf_id = Util.getIntValue(rs.getString("id"));
                String requestid = Util.null2String(rs.getString("reqid"));
                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 requestName = lcbh + bt + "的预付款费用确认";
                String bz = "收款方： " + skdw;
                logger.info("预付款流程确认标题==" + requestName);
//                预付款流程
                String mark = CoWfUtil.getRequestMarkByUnNumber("zbyfkfyqr", Sequences.NET_REI_WORKFLOW_SEQ_ZB);

                requestMainMap.put("ngr", ngr);
                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);
                logger.info("预付款流程生成过滤后参数==" + JSON.toJSONString(requestMainMap));
                //2.自动创建流程获取requestid
                int requestid_main_213 = Util.getIntValue(WorkflowCreateByRequestMap(ngr, workflowId, requestName, IsNextFlow, requestMainMap));
                logger.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.更新流程编号
                    logger.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,bhsje,sj,jshjje,sy,fysjcdbm,sl,yskm,slz,htbh,cys,yskmid) " +
                            " select  " + form_id + ",bhsje,sj,jshjje,sy,fysjcdbm,sl,yskm,'' as slz,'' as htbh,cys,'" + yskmPre + "_'||yskm from " + mainTable + "_dt8 where mainid = " + uf_id + "";
                    logger.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,'' as htbh,sy,bz,hl,wbje,yskm,fysjcdbm,cys,'" + yskmPre + "_'||yskm from " + mainTable + "_dt9 where mainid = " + uf_id + "";
                    logger.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 " + mainTable + "_dt11 where mainid = " + uf_id + "";
                    logger.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 " + mainTable + "_dt12 where mainid = " + uf_id + "";
                    logger.info("批量插入sql明细表12==" + detail_twelve_sql);
                    rst.executeUpdate(detail_twelve_sql);
                }
            }
            rst.commit();
            createSuccess.add(requestidAndLcbh);
//            }
        } catch (Exception e) {
            result.put("isSuccess", false);
            result.put("successMes", createSuccess);
            result.put("errorMes", "创建流程失败，请联系管理员");
            logger.error("存在创建失败的流程：" + e.getMessage());
        }
        if (createSuccess.size() != 0) {
            result.put("isSuccess", true);
            result.put("successMes", createSuccess.get(0));
            result.put("errorMes", "");
        }
        return result;
    }


    /**
     * 根据流程编号返回具体的查询sql
     *
     * @param requestidAndLcbh
     * @return
     */
    private Map<String, String> getSelectSql(String requestidAndLcbh) {
        Map<String, String> result = new HashMap<>();
        logger.info("====================进入主表数据的获取sql================");
        String requestid = requestidAndLcbh.split("&")[0];
        String lcbh = Util.null2String(requestidAndLcbh.split("&")[1]);
        if (lcbh.contains("总部通用付款")) {
            Map<String, String> zbtyfk = buildGetMainSql("zbtyfk", requestid);
            result.put("sql", zbtyfk.get("sql"));
            result.put("mainTable", zbtyfk.get("mainTable"));
        }
        if (lcbh.contains("总部工会付款")) {
//            该流程中费用会计审批节点固定设置的张璇，所以设置的27827
            Map<String, String> zbghfk = buildGetMainSql("zbghfk", requestid);
            result.put("sql", zbghfk.get("sql"));
            result.put("mainTable", zbghfk.get("mainTable"));
        }
        if (lcbh.contains("总部IT付款")) {
            Map<String, String> zbitfk = buildGetMainSql("zbitfk", requestid);
            result.put("sql", zbitfk.get("sql"));
            result.put("mainTable", zbitfk.get("mainTable"));
        }
        if (lcbh.contains("分支机构通用付款")) {
            Map<String, String> fzjgtyfk = buildGetMainSql("fzjgtyfk", requestid);
            result.put("sql", fzjgtyfk.get("sql"));
            result.put("mainTable", fzjgtyfk.get("mainTable"));
        }
        if (lcbh.contains("托收业务流程")) {
            Map<String, String> tsywlc = buildGetMainSql("tsywlc", requestid);
            result.put("sql", tsywlc.get("sql"));
            result.put("mainTable", tsywlc.get("mainTable"));
        }
        logger.info("=-=-=-=-=-=-=-=-=-=-=-=-返回的结果是：" + JSONObject.toJSONString(result) + "=-=-=-=-=-=-=-=-=-=-=-=-");
        return result;
    }

    /**
     * 移除map中的空值数据
     *
     * @param map
     * @return
     */
    private 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;
    }

    /**
     * @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
     * @Title: 自动创建流程
     */
    public static String WorkflowCreateByRequestMap(String creatorId, String workflowId,
                                                    String requestName, String IsNextFlow,
                                                    Map<String, String> requestMainMap) {
        com.weaver.general.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;
    }


    /**
     * 根据流程类型获取数据写入需要的主表数据查询sql
     *
     * @param type      流程类型
     * @param requestId 付款流程requestId
     * @return 查询sql
     */
    private Map<String, String> buildGetMainSql(String type, String requestId) {
        StringBuilder sql = new StringBuilder();
        RecordSet rs = new RecordSet();
        String fromtable = "";
        Map<String, String> result = new HashMap<>();
        rs.executeQuery("select fromtable,reqid,lcbh,ngr,szbm,jjcd,jjyy,lxfs,ngsj,xjhjmx,ngrfyhj,fyhjsp,ggfyqtfy,fkxx,fzjgcwjl from uf_yfkfyqrzjb where lclx = '" + type + "'");
        if (rs.next()) {
            fromtable = rs.getString("fromtable");
            sql.append("select a.id,c.requestname as bt");
            for (String column : rs.getColumnName()) {
                if (!"FROMTABLE".equals(column)) {
                    sql.append(",");
                    if (!"".equals(rs.getString(column))) {
                        sql.append("a.").append(rs.getString(column)).append(" as ").append(column.toLowerCase());
                    } else {
                        sql.append("'' as ").append(column.toLowerCase());
                    }
                }
            }
            sql.append(",(select wm_concat_old(b.skdw) from ").append(fromtable).append("_dt11 b where a.id = b.mainid)")
                    .append("as skdw from ").append(fromtable).append(" a join workflow_requestbase c on a.requestid = c.requestid")
                    .append(" where a.requestid = '").append(requestId).append("'");
        }
        result.put("sql", String.valueOf(sql));
        result.put("mainTable", fromtable);
        return result;
    }

}
