package weaver.interfaces.htsc.job.workflow;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.engine.common.util.ServiceUtil;
import com.engine.workflow.service.WorkflowRuleService;
import com.engine.workflow.service.impl.WorkflowRuleServiceImpl;
import weaver.conn.RecordSet;
import weaver.conn.RecordSetDataSource;
import weaver.general.GCONST;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.integration.logging.Logger;
import weaver.integration.logging.LoggerFactory;
import weaver.interfaces.htsc.comInfo.PropBean;
import weaver.interfaces.schedule.BaseCronJob;
import weaver.workflow.agent.AgentBean;
import weaver.workflow.agent.AgentDateBean;
import weaver.workflow.agent.AgentManager;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 *
 * @ClassName: AgentSetJob
 * @Description: TODO(定时任务读取门户的代理设置)
 * @author Created by K1810006
 * @date 2020年11月24日09:32:22
 *
 */

/**
 * method: add
 * isProxyForward:   代理转发
 * endDate: 2021-03-03  代理结束日期
 * isCreateAgenter: 0   代理流程创建
 * isProxyDeal: 1     代理流程处理
 * bagentuid: 1    被代理人
 * beginDate: 2021-03-03  代理开始日期
 * rangetype: 24     代理的流程
 * agentuid: 24209   代理人
 * beginTime: 15:00  代理开始时间
 * endTime: 16:00    代理结束时间
 * isSysCreateAgenter:
 * isPendThing:  代理已有待办事宜
 * agentrange: 1   代理流程范围
 */


public class AgentSetJob extends BaseCronJob {

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

    public static boolean checklock = true;


    @Override
    public void execute() {

        Long begintime = System.currentTimeMillis();
        logger.info(">>>>>>>>>>>>>>>>>>>>>>>" + this.getClass().getName() + ":strat");

        if (checklock) {
            checklock = false;
            try {
                User user = User.getUser(1,0);
                WorkflowRuleService ruleService = (WorkflowRuleServiceImpl) ServiceUtil.getService(WorkflowRuleServiceImpl.class, user);
                RecordSet rs = new RecordSet();
                RecordSetDataSource rds  = new RecordSetDataSource("EipAgent");
                RecordSetDataSource rds2  = new RecordSetDataSource("EipAgent");
                RecordSetDataSource rds3  = new RecordSetDataSource("EipAgent");

                DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:00:00");
                Calendar cal = Calendar.getInstance();
                cal.add(Calendar.HOUR, -1);
                String synTime = format.format(cal.getTime());

                //删除原有授权数据
                deleteOldData(user,synTime);

                String dataSql = " select distinct t1.client,t1.clientDeptCode,t1.workflowname,t1.starttime,t1.endtime \n" +
                        " from ENTRUSTOA t1, zony_wfp_pe.entrust_portal_info t2 \n" +
                        " where t1.portal_id=to_char(t2.id)\n" +
                        " and t1.workflowname like 'ECOA%' and t1.enable=1  \n" +
                        " and t2.createtime >= '"+synTime+"'";
                logger.info(">>>>>>>>>>>>>>>>>>>>>>>AgentSetJob syn dataSql========"+dataSql);

                rds.execute(dataSql);
                while(rds.next()){
                    String client = Util.null2String(rds.getString("client"));//授权人工号
                    String clientDeptCode = Util.null2String(rds.getString("clientDeptCode"));//授权人部门编码
                    String wfname = Util.null2String(rds.getString("workflowname")); //授权流程
                    String wfunnumber = wfname.substring(5);
                    int beagenterid = getUidByWorkcodeAndDeptcode(client,clientDeptCode);
                    if(beagenterid<0){
                        continue;
                    }
                    String workflowid = new PropBean().getActiveWorkflowIdByUnNumber(wfunnumber);
                    String endtime = Util.null2String(rds.getString("endtime")); //授权结束时间
                    String starttime = Util.null2String(rds.getString("starttime")); //授权开始时间
                    //重新同步门户的授权数据
                    String beginDate = "";
                    String beginTime = "";
                    if(!"".equals(starttime)){
                        beginDate = starttime.substring(0,10);
                        beginTime = starttime.substring(11,16);
                    }

                    String finishDate = "";
                    String finishTime = "";
                    if(!"".equals(endtime)){
                        finishDate = endtime.substring(0,10);
                        finishTime = endtime.substring(11,16);
                    }


                    //查询当前流程、当前代理人的所有有效配置
                    ArrayList<AgentBean> detailList = new ArrayList();
                    String allDataSql = " select distinct trustee,starttime,endtime from ENTRUSTOA " +
                            "where workflowname='"+wfname+"' and client='"+client+"' " +
                            " and clientDeptCode='"+clientDeptCode+"' and starttime='"+starttime+"' " +
                            " and endtime='"+endtime+"' and enable=1 ";
                    rds2.execute(allDataSql);
                    while(rds2.next()){
                        String trustee = Util.null2String(rds2.getString("trustee")); //被授权人工号（如果被授权人有多个身份，则授权给同部门的身份）
                        int agentuid = getUidByWorkcodeAndDeptcode(trustee,clientDeptCode);
                        logger.info("client="+client+"  clientDeptCode="+clientDeptCode+"  trustee="+trustee);
                        if(agentuid<0){
                            continue;
                        }

                        //生成对应代理人的条件规则
                        String linkid = getLinkid();
                        logger.info("AgentSetJob linkid=="+linkid);

                        //生成代理条件参数
                        Map<String,Object> allcondition = new HashMap<String,Object>();
                        rds3.execute(" select distinct condition from ENTRUSTOA t1 " +
                                " where client='"+client+"' and trustee='"+trustee+"' and clientdeptcode='"+clientDeptCode+"' " +
                                " and workflowname = '"+wfname+"' and starttime='"+starttime+"' and endtime='"+endtime+"' and enable=1  ");
                        while(rds3.next()) {
                            String condition = Util.null2String(rds3.getString("condition")); //授权条件
                            logger.info("AgentSetJob condition==="+condition);
                            if (!"".equals(condition)) {
                                Map<String,String> conditionMap = conditionStrToMap(condition);
                                parseCondition(allcondition,conditionMap,workflowid);

                            }
                        }

                        String conditionss  = "";
                        //如果有设置代理规则，解析规则
                        if(allcondition.size()>0){
                            Map<String,Object> params = getContionParams(allcondition,workflowid,linkid);
                            logger.info("AgentSetJob saveRule params==========="+params);

                            Map res = ruleService.saveRule(params);
                            JSONObject jsonRes = new JSONObject(res);
                            if("SUCCESS".equals(jsonRes.getString("info"))) {
                                conditionss  = jsonRes.getString("id");
                            }

                        }


                        //构造明细参数
                        AgentBean agentBean = new AgentBean();
                        agentBean.setAgentuid(agentuid);
                        agentBean.setIscreateagenter(1);
                        agentBean.setIsSysCreateAgenter("1");
                        agentBean.setIsproxydeal(1);
                        agentBean.setIspendthing(0);
                        agentBean.setAgentbatch("0.00");
                        agentBean.setConditionkeyid(linkid);
                        agentBean.setConditionss(conditionss);
                        //agentBean.setConditioncn();
                        detailList.add(agentBean);


                    }

                    if(detailList.size()==0){
                        continue;
                    }

                    AgentBean bean = detailList.get(0);
                    bean.setBagentuid(beagenterid);
                    bean.setBegindate(beginDate);
                    bean.setBegintime(beginTime);
                    bean.setEnddate(finishDate);
                    bean.setEndtime(finishTime);

                    //第一步 添加出被代理人的代理记录
                    logger.info("AgentSetJob   insert agent===="+JSON.toJSONString(bean));
                    AgentManager agentManager = new AgentManager(user);
                    String agentresult = agentManager.addAgent(workflowid, bean, 1);
                    logger.info("AgentSetJob agentresult==="+agentresult);
                    int agentid = -1;
                    if(!"success".equals(agentresult)){
                        logger.error("AgentSetJob 同步门户代理数据出错，授权人："+beagenterid+" 被授权人："+bean.getAgentid()+" 授权流程："+wfunnumber);
                    }else{
                        //查询生成的代理数据id
                        int agentuid = bean.getAgentuid();
                        String agentSql = "    select * from workflow_agent " +
                                " where workflowid="+workflowid+" and beagenterid="+beagenterid+" and agenterid="+agentuid+" " +
                                " and begindate='"+beginDate+"' and begintime='"+beginTime+"' " +
                                " and enddate='"+finishDate+"' and endtime='"+finishTime+"'  " ;
                        rs.execute(agentSql);
                        rs.next();
                        agentid = rs.getInt("agentid");
                    }

                    //第二部 给被代理人添加所有的代理明细记录
                    AgentDateBean agentDateBean = new AgentDateBean();
                    agentDateBean.setBegindate(beginDate);
                    agentDateBean.setBegintime(beginTime);
                    agentDateBean.setEnddate(finishDate);
                    agentDateBean.setEndtime(finishTime);
                    String detailResult = agentManager.changeAgentSet(agentid, agentDateBean, 2, true, detailList);
                    logger.info("保存明细数据结果===="+detailResult);

                    //生成代理数据的条件

                }
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                checklock = true;
            }


        } else {
            logger.info(this.getClass().getName() + "正在执行中...");
        }

        logger.info(">>>>>>>>>>>>>>>>>>>>>>>" + this.getClass().getName() + ":end 耗时：" + (System.currentTimeMillis() - begintime));



    }

    /**
     * 根据工号和部门编码查询人员ID
     * @param workcode
     * @param deptcode
     * @return
     */
    public int getUidByWorkcodeAndDeptcode(String workcode,String deptcode){
        //System.out.println(workcode+"  "+deptcode);
        int userid = -1;
        RecordSet rs = new RecordSet();
        rs.executeQuery(" select a.id from hrmresource a,hrmdepartment b" +
                " where a.departmentid=b.id and workcode=? and departmentcode=? and status<=3 ",new Object[]{workcode,deptcode});
        if(rs.next()){
            userid = rs.getInt("id");
        }
        return userid;

    }


    /**
     * 将条件字段转为键值对
     * @param condition
     * @return
     */
    public Map<String,String> conditionStrToMap(String condition){
        Map<String,String> conditionKV = new LinkedHashMap<>();
        String[] conditions = condition.split(";");
        for(int i=0;i<conditions.length;i++){
            String fieldname = conditions[i].split("=")[0];
            String fieldvalue = conditions[i].split("=")[1];
            conditionKV.put(fieldname,fieldvalue);
        }
        return conditionKV;
    }


    /**
     * 解析单条代理的条件
     * @param condition
     * @return
     */
    public Map<String,Object> parseCondition(Map<String,Object> allcondition,Map<String,String> condition,String workflowid){
        RecordSet rs = new RecordSet();
        for (Map.Entry<String, String> entry : condition.entrySet()) {
            String fieldname = entry.getKey();
            String fieldvalue = entry.getValue();

            String fieldSql = "select b.*,c.labelname from workflow_base a,workflow_billfield b,htmllabelinfo c " +
                    " where a.formid=b.billid and b.fieldlabel=c.indexid and c.languageid=7 " +
                    " and a.id=? and b.fieldname=? ";
            rs.executeQuery(fieldSql,new Object[]{workflowid,fieldname});
            if(rs.next()){
                String fieldid = Util.null2String(rs.getString("id"));
                String fielddbtype = Util.null2String(rs.getString("fielddbtype"));
                String fieldhtmltype = Util.null2String(rs.getString("fieldhtmltype"));
                //int pubchilchoiceid = Util.getIntValue(rs.getString("pubchilchoiceid"));
                int type = rs.getInt("type");
                String labelname = Util.null2String(rs.getString("labelname"));

                //判断是否是人力资源字段
                int typehrm = -1;
                if("3".equals(fieldhtmltype) && (type==1 || type==17)){
                    typehrm = 1;
                }

                String browservalue = "";
                String browserspantext = "";
                String browserspanlabel = "";
                String selectvalue1 = "-1";
                if("5".equals(fieldhtmltype)){//下拉框值转换，浏览按钮情况暂不处理
                    String selectRange = "";
                    rs.executeQuery(" select id,fieldname from workflow_billfield where childfieldid=? ",fieldid);
                    if(rs.next()){//是子选项，需要根据父选项确定下拉框的值

                        String parentFieldid = Util.null2String(rs.getString("id"));
                        String parentFieldname = Util.null2String(rs.getString("fieldname"));
                        String parentFieldvalue = condition.get(parentFieldname);

                        rs.executeQuery(" select childitemid from workflow_selectitem where fieldid=? and selectname=?  ",new Object[]{parentFieldid,parentFieldvalue} );
                        rs.next();
                        String childitemid = Util.null2String(rs.getString("childitemid"));

                        if(!"".equals(childitemid)){
                            selectRange = " and selectvalue in ("+childitemid+") ";
                        }

                    }

                    rs.executeQuery(" select selectvalue from workflow_selectitem " +
                            "where fieldid=? and selectname=? "+selectRange,new Object[]{fieldid,fieldvalue});
                    rs.next();
                    String selectvalue = Util.null2String(rs.getString("selectvalue"));
                    browservalue = selectvalue;
                    browserspantext = fieldvalue;
                    browserspanlabel = fieldvalue;
                    selectvalue1 = selectvalue;
                }

                String textvalue1 = "";
                if("2".equals(fieldhtmltype)){
                    textvalue1 = fieldvalue;
                }

                String valuetype = "-1";
                if("2".equals(fieldhtmltype)){
                    valuetype = "1";
                }

                Map<String,Object> fieldConditionInfo = new HashMap<String,Object>();
                if(allcondition.containsKey(fieldname)){
                    fieldConditionInfo = (Map<String, Object>) allcondition.get(fieldname);
                    fieldConditionInfo.put("browservalue",((String)fieldConditionInfo.get("browservalue"))+","+browservalue);
                    fieldConditionInfo.put("browserspantext",((String)fieldConditionInfo.get("browserspantext"))+"_"+browserspantext);
                    fieldConditionInfo.put("browserspanlabel",((String)fieldConditionInfo.get("browserspanlabel"))+","+browserspanlabel);
                    fieldConditionInfo.put("selectvalue1",((String)fieldConditionInfo.get("selectvalue1"))+","+selectvalue1);

                }else{
                    fieldConditionInfo.put("datafield",fieldid);
                    fieldConditionInfo.put("datafieldlabel",labelname);
                    fieldConditionInfo.put("typehrm",typehrm);
                    fieldConditionInfo.put("htmltype",fieldhtmltype);
                    fieldConditionInfo.put("fieldtype",type);
                    fieldConditionInfo.put("dbtype",fielddbtype);
                    fieldConditionInfo.put("browservalue",browservalue);
                    fieldConditionInfo.put("browserspantext",browserspantext);
                    fieldConditionInfo.put("browserspanlabel",browserspanlabel);
                    fieldConditionInfo.put("textvalue1",textvalue1);
                    fieldConditionInfo.put("valuetype",valuetype);
                    fieldConditionInfo.put("selectvalue1",selectvalue1);


                }
                allcondition.put(fieldname,fieldConditionInfo);
            }
        }

        return allcondition;

    }


    /**
     * 生成条件参数
     * @param allcondition
     * @param workflowid
     * @param linkid
     * @return
     */
    public Map<String,Object> getContionParams(Map<String,Object> allcondition,String workflowid,String linkid){

        String returnStr[] = new String[2];
        String rulexml = "<?xml version='1.0' encoding='utf-8'?><expressions relation='1'>";
        String condit = "";

        for (Map.Entry<String, Object> entry : allcondition.entrySet()) {
            String fieldname = entry.getKey();
            Map<String,Object> conditionInfo = (Map<String, Object>) entry.getValue();

            String xmlStr = "<expression \n" +
                    "          id='-1'\n" +
                    "          paramtype='-1'\n" +
                    "          datafield='"+conditionInfo.get("datafield")+"'\n" +
                    "          datafieldlabel='"+conditionInfo.get("datafieldlabel")+"'\n" +
                    "          typehrm='"+conditionInfo.get("typehrm")+"'\n" +
                    "          htmltype='"+conditionInfo.get("htmltype")+"'\n" +
                    "          fieldtype='"+conditionInfo.get("fieldtype")+"'\n" +
                    "          dbtype='"+conditionInfo.get("dbtype")+"'\n" +
                    "          compareoption1='7'\n" +
                    "          compareoption2='-1'\n" +
                    "          browservalue='"+conditionInfo.get("browservalue")+"'\n" +
                    "          browserspantext='"+conditionInfo.get("browserspantext")+"'\n" +
                    "          browserspanlabel='"+conditionInfo.get("browserspanlabel")+"'\n" +
                    "          browservalue2=''\n" +
                    "          browserspantext2=''\n" +
                    "          browserspanlabel2=''\n" +
                    "          textvalue1='"+conditionInfo.get("textvalue1")+"'\n" +
                    "          textvalue2=''\n" +
                    "          valuetype='"+conditionInfo.get("valuetype")+"'\n" +
                    "          valuetype2='-1'\n" +
                    "          checkboxvalue1='-1'\n" +
                    "          redius='-1'\n" +
                    "          nodeId=''\n" +
                    "          selectvalue1='"+conditionInfo.get("selectvalue1")+"'\n" +
                    "          meetCondition='-1'\n" +
                    "          jingdu=''\n" +
                    "          weidu=''\n" +
                    "          hrmConditon = ''\n" +
                    "          hrmConditonValue=''\n" +
                    "       /> \n";
            rulexml += xmlStr;
            condit +=  "("+conditionInfo.get("datafieldlabel")+" 属于 '"+conditionInfo.get("browserspanlabel")+"') AND ";
        }

        rulexml += "</expressions>";

        condit = condit.substring(0,condit.lastIndexOf("AND")).trim();
        condit = "("+condit+")";

        int formid = getFormId(workflowid);

        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("rulexml",rulexml);
        paramsMap.put("rownum","");
        paramsMap.put("condit",condit);
        paramsMap.put("e9nodeid","");
        paramsMap.put("ruleid",0);
        paramsMap.put("rulesrc",6);
        paramsMap.put("formid",formid);
        paramsMap.put("linkid",linkid);
        paramsMap.put("isbill",1);
        paramsMap.put("wfid",workflowid);

        return paramsMap;

    }

    /**
     * 查询流程对应表单id
     * @param workflowid
     * @return
     */
    public int getFormId(String workflowid){
        int formid = -1;
        RecordSet rs = new RecordSet();
        rs.executeQuery(" select formid from workflow_base where id=? ",new Object[]{workflowid});
        if(rs.next()){
            formid = rs.getInt("formid");
        }
        return formid;
    }



    public static String getLinkid(){
        String rnd = "";
        for (int i = 0; i < 2; i++) {
            rnd += new Random().nextInt(10);
        }
        return  Calendar.getInstance().get(Calendar.MILLISECOND) +rnd;

    }


    /**
     * 删除代理人关于当前流程的所有代理数据
     * @param workflowid
     * @param beagenterid
     */
    public void deleteAgentData(String workflowid,int beagenterid){
        RecordSet rs = new RecordSet();
        String conditionkeyid = "";
        String sql1 = " select b.* from workflow_agent a,workflow_agentConditionSet b " +
                "where a.agentid=b.agentid and a.beagenterid=? and a.workflowid=? and conditionkeyid is not null ";
        rs.executeQuery(sql1,new Object[]{beagenterid,workflowid});
        while(rs.next()){
            conditionkeyid += Util.null2String(rs.getString("conditionkeyid"))+",";
        }

        if(!"".equals(conditionkeyid)){
            conditionkeyid = conditionkeyid.substring(0,conditionkeyid.length()-1);

            //删除规则
            String deleteSql1 = "  delete from rule_maplist where wfid="+workflowid+" and rulesrc=6 and linkid in("+conditionkeyid+")";
            rs.execute(deleteSql1);

            String deleteSql2 = " delete from rule_base where linkid in("+conditionkeyid+") and rulesrc=6 ";
            rs.execute(deleteSql2);
        }




        String deleteSql3 = " delete from workflow_agentConditionSet a " +
                "where exists(select 1 from workflow_agent b  " +
                "where a.agentid = b.agentid and b.workflowid=? and b.beagenterid=? )";
        rs.executeUpdate(deleteSql3,new Object[]{workflowid,beagenterid});

        String deleteSql4 = " delete from workflow_agent where workflowid=? and beagenterid=? ";
        rs.executeUpdate(deleteSql4,new Object[]{workflowid,beagenterid});


    }




    /**
     * 收回代理人关于当前流程的所有代理数据
     * @param workflowid
     * @param beagenterid
     */
    public void takeBackAgentData(String workflowid,int beagenterid,User user){
        RecordSet rs = new RecordSet();
        String sql = " select agentid from workflow_agent where beagenterid=? and workflowid=? and agenttype=1 ";
        rs.executeQuery(sql,new Object[]{beagenterid,workflowid});
        AgentManager agentManager = new AgentManager(user);
        while(rs.next()){
            int agentid = rs.getInt("agentid") ;
            agentManager.takeBackAgent(agentid, true,true);
        }
    }


    /**
     * 删除OA中当前流程、当前代理人的所有代理数据
     */
    public void deleteOldData(User user,String synTime){
        RecordSetDataSource rds  = new RecordSetDataSource("EipAgent");
        String dataSql = " select distinct t1.client,t1.clientDeptCode,t1.workflowname,t1.starttime,t1.endtime \n" +
                "from ENTRUSTOA t1, zony_wfp_pe.entrust_portal_info t2 \n" +
                "where t1.portal_id=to_char(t2.id) and t1.workflowname like 'ECOA%'  \n" +
                "and t2.createtime >= '"+synTime+"' ";
        logger.info(">>>>>>>>>>>>>>>>>>>>>>>AgentSetJob delete dataSql========"+dataSql);
        rds.execute(dataSql);
        while(rds.next()) {
            String client = Util.null2String(rds.getString("client"));//授权人工号
            String clientDeptCode = Util.null2String(rds.getString("clientDeptCode"));//授权人部门编码
            String wfname = Util.null2String(rds.getString("workflowname")); //授权流程
            String wfunnumber = wfname.substring(5);
            int beagenterid = getUidByWorkcodeAndDeptcode(client, clientDeptCode);
            if (beagenterid < 0) {
                continue;
            }
            String workflowid = new PropBean().getActiveWorkflowIdByUnNumber(wfunnumber);
            //删除OA中当前流程、当前代理人的所有代理数据
            //deleteAgentData(workflowid, beagenterid);
            takeBackAgentData(workflowid,beagenterid,user);
        }

    }




    public static void main(String[] args) {

        GCONST.setRootPath("./");
        GCONST.setServerName("ecology");

        AgentSetJob agentSetJob = new AgentSetJob();
        agentSetJob.execute();

    }


}
