package weaver.interfaces.htsc.util;

import weaver.conn.RecordSet;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.hrm.resource.ResourceComInfo;
import weaver.soa.workflow.request.*;
import weaver.system.RequestDefaultComInfo;
import weaver.system.SysWFLMonitor;

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

public class WfUtil {

    /** 流程中的签字意见类型映射 */
    static final Map<String, String> LOG_TYPE_MAPPER;

    static {
        Map<String, String> m = new HashMap<String, String>(32);
        m.put("0", "批准");
        m.put("1", "保存");
        m.put("2", "提交");
        m.put("3", "退回");
        m.put("4", "重新打开");
        m.put("5", "删除");
        m.put("6", "激活");
        m.put("7", "转发");
        m.put("9", "批注");
        m.put("a", "意见征询");
        m.put("b", "意见征询回复");
        m.put("h", "转办");
        m.put("i", "干预");
        m.put("j", "转办反馈");
        m.put("e", "强制归档");
        m.put("s", "督办");
        m.put("t", "抄送");
        LOG_TYPE_MAPPER = Collections.unmodifiableMap(m);
    }

    /**
     * 根据表单ID查询表单名称（只支持新表单）
     * @param formid 表单id
     * @return 表名
     */
    public static String getTableNameByFormID(int formid){
        return SqlUtil.querySingleField("  SELECT TABLENAME FROM WORKFLOW_BILL WHERE ID=? ",formid);

    }


    /**
     * 根据流程ID查询表单名称
     * @param workflowid 流程id
     * @return 表名
     */
    public static String getTableNameByWorkflowID(String workflowid){
        if(workflowid!=null && !"".equals(workflowid)){
            int formid = Util.getIntValue(SqlUtil.querySingleField(" SELECT FORMID FROM WORKFLOW_BASE WHERE ID=? ",workflowid));
            return getTableNameByFormID(formid);
        }
        return "";
    }


    /**
     * 根据流程请求ID查询表单名称
     * @param requestid 流程请求id
     * @return 表名
     */
    public static String getTableNameByRequestID(String requestid){
        if(requestid!=null && !"".equals(requestid)){
            String sql = " SELECT TABLENAME FROM WORKFLOW_REQUESTBASE T1,WORKFLOW_BASE T2,WORKFLOW_BILL T3\n" +
                    "WHERE T1.WORKFLOWID=T2.ID AND T2.FORMID=T3.ID AND T1.REQUESTID=? ";
            System.out.println("getTableNameByRequestID sql======"+sql);
            return SqlUtil.querySingleField(sql,requestid);
        }
        return "";
    }

    /**
     * 根据流程实例ID查询表单ID
     * @param requestId 流程请求id
     * @return 表单id
     */
    public static int getBillIdByRequestId(String requestId) {
        String sql = " SELECT BASE.FORMID AS FORMID"
                + " FROM WORKFLOW_BASE BASE"
                + " LEFT OUTER JOIN WORKFLOW_REQUESTBASE REQ ON BASE.ID=REQ.WORKFLOWID"
                + " WHERE REQ.REQUESTID=? ";
        return Util.getIntValue(SqlUtil.querySingleField(sql, requestId));
    }

    /**
     * 根据流程实例ID查询workflowid
     * @param requestId 流程请求id
     * @return 流程id
     */
    public static int getWorkflowIdByRequestId(int requestId) {
        String sql = " select req.workflowid as workflowid"
                + " from workflow_requestbase req"
                + " where req.requestid=? ";
        return Util.getIntValue(SqlUtil.querySingleField(sql, requestId));
    }



    /**
     * 根据requestId获取流程实例标题
     *
     * @param requestId 流程请求id
     * @return 流程实例标题
     */
    public static String getRequestName(final int requestId) {
        String sql = "SELECT REQUESTNAME FROM WORKFLOW_REQUESTBASE WHERE REQUESTID =? ";
        return SqlUtil.querySingleField(sql, requestId);
    }


    /**
     * 查询请求实例主表数据
     * @param requestId 流程请求id
     * @return 流程请求主表数据
     */
    public static Map<String, String> getRequestMainTableData(String requestId) {
        String billTableName = getTableNameByRequestID(requestId);
        return queryRequestMainData(billTableName, requestId);
    }

    /**
     * 查询流程请求实例主表数据
     * @param tableName 流程表名
     * @param requestId 流程请求id
     * @return 流程请求主表数据
     */
    public static Map<String, String> queryRequestMainData(String tableName, String requestId) {
        String sql = " SELECT * FROM " + tableName + " WHERE REQUESTID =? ";
        return SqlUtil.queryDataToMap(sql,requestId);
    }


    /**
     * 根据流程实例查询对应明细表的数据
     * @param requestId 流程请求id
     * @param dtnum 明细表序号
     * @return 流程请求明细表数据
     */
    public static List<Map<String, String>> queryRequestDetailData(String requestId, int dtnum) {
        String tableName = getTableNameByRequestID(requestId);
        int mainid = getMainId(requestId);
        // 明细表表名
        String detailTableName = tableName+"_dt"+dtnum;
        String sql = "SELECT * FROM " + detailTableName + " where mainid=? ";
        return SqlUtil.queryDataToList(sql,mainid);
    }


    /**
     * 保存流程页面（请提前配置流程存为文档，并至少提前一个节点触发使其生成文档）
     * 服务器保存的文件名为{requestid}.html
     *
     * @param requestId 请求id
     * @param path      保存路径
     * @return 保存的全路径
     */
    public static String saveWorkflowToHtml(int requestId, String path) {
        String sql = "select max(id) id from DocDetail where fromworkflow = " + requestId;
        int docid = Util.getIntValue(SqlUtil.querySingleField(sql));
        if (docid == -1){
            return "";
        }
        return DocUtil.saveDoc(docid, path, requestId + ".html");
    }


    /**
     * 查询流程未操作者
     * @param requestid 流程请求id
     * @param userid 当前操作人
     * @return 流程当前未操作者
     */
    public static String getUnoperators(String requestid,String userid){
        User user = User.getUser(Integer.parseInt(userid),0);
        String language = user.getLanguage()+"";
        ResourceComInfo rc = null;
        try {
            rc = new ResourceComInfo();
        } catch (Exception e) {
            e.printStackTrace();
        }

        String unoperatorType = "";
        RequestDefaultComInfo rdComInfo = new RequestDefaultComInfo();
        unoperatorType = Util.null2String(rdComInfo.getUnoperatorType(userid));
        if("".equals(unoperatorType)){
            unoperatorType = "1,2,3,4,5,6";//默认显示全部类型
        }

        List<String> unoperatorTypes = Util.TokenizerString(unoperatorType, ",");
        String isremarkStr = " (1 = 2 or ";
        //--------------------处理isremark条件----------------------
        if (unoperatorTypes.contains("1")) {//节点操作者
            isremarkStr += " (isremark = 0 or (isremark = 4 and viewtype = 0 and preisremark = 0) or (isremark = 1 and takisremark = '2')) or ";
        } else if (unoperatorTypes.contains("2")) {//转办操作者
            isremarkStr += " (isremark = 0 and (takisremark is null or takisremark=0) and handleforwardid > 0) or ";
        }

        if (unoperatorTypes.contains("4") && unoperatorTypes.contains("5")) {
            isremarkStr += " (isremark in(8,9,11) or (isremark = 4 and viewtype = 0 and preisremark in(8,9))) or ";
        } else if (unoperatorTypes.contains("4")) {//抄送操作者
            isremarkStr += " (isremark in(8,9) or (isremark =4 and viewtype = 0 and preisremark in(8,9))) or ";
        } else if (unoperatorTypes.contains("5")) {//传阅操作者
            isremarkStr += " (isremark in(11)) or ";
        }

        if (unoperatorTypes.contains("3")) {//转发操作者
            isremarkStr += " (isremark = 1 and (takisremark <>'2' or takisremark is null)) or ";
        }
        if (unoperatorTypes.contains("6")) {//其他操作者--协办、超时干预到指定对象
            isremarkStr += " (isremark in(5,7)) or ";
        }
        isremarkStr += " 1=2)";
        //--------------------处理isremark条件----------------------
        //--------------------分页----------------------
        String returnStr = "";
        List<String> unOperators = new ArrayList<>();
        RecordSet rs = new RecordSet();
        rs.execute("select userid,usertype,agenttype,agentorbyagentid,isremark,showorder,id,groupid from workflow_currentoperator where islasttimes =1 and requestid = " + requestid + " and " + isremarkStr + " order by isremark,groupid,showorder asc ,id asc");

        //--------------------分页----------------------
        while (rs.next()) {
            //去除重复
            String key = rs.getString("userid") + ":" + rs.getString("usertype") + ":" + rs.getString("agenttype") + ":" + rs.getString("agentorbyagentid");
            if (unOperators.contains(key)) {
                continue;
            } else {
                unOperators.add(key);
            }
            if (rs.getInt("agenttype") == 2) {
                returnStr += Util.formatMultiLang(rc.getResourcename(rs.getString("userid")), language)+"（"+Util.formatMultiLang(rc.getResourcename(rs.getString("agentorbyagentid")), language) + "授权）"  + " ";
                //判断是否被代理者,如果是，则不显示该记录
            } else if (rs.getInt("agenttype") == 1 && rs.getInt("isremark") == 4) {
                continue;
            } else {
                returnStr += Util.formatMultiLang(rc.getResourcename(rs.getString("userid")), language) + " ";
            }
        }
        return returnStr;
    }

    /**
     * 查询表单字段
     * @param workflowid 流程id
     * @param detailNum 明细表序号
     * @return 表单字段
     */
    public static Map<String,String> getBillFieldMapper(String workflowid,int detailNum){
        Map<String,String> data = new HashMap<String,String>();
        String sql = " SELECT T3.ID,T3.FIELDNAME FROM WORKFLOW_BASE T1,WORKFLOW_BILL T2,WORKFLOW_BILLFIELD T3 " +
                " WHERE T1.FORMID=T2.ID AND T2.ID=T3.BILLID AND T1.ID=? ";
        if(detailNum>0){
            sql += " AND DETAILTABLE LIKE '%dt"+detailNum+"' ";
        }else{
            sql += " AND (DETAILTABLE IS NULL OR DETAILTABLE = '') ";
        }

        RecordSet rs = new RecordSet();
        rs.executeQuery(sql,workflowid);
        while(rs.next()){
            String fieldId = Util.null2String(rs.getString("ID"));
            String fieldName = Util.null2String(rs.getString("FIELDNAME"));
            data.put(fieldName,fieldId);
        }
        return data;

    }

    /**
     * 根据字段fieldid查询对应下拉选项
     * @param fieldid 字段id
     * @return 下拉框键值对
     */
    public static Map<String,String> getSelectItem(String fieldid){
        Map<String,String> data = new HashMap<String,String>();
        String sql = " SELECT SELECTNAME,SELECTVALUE FROM WORKFLOW_SELECTITEM WHERE FIELDID=? ";
        RecordSet rs = new RecordSet();
        rs.executeQuery(sql,fieldid);
        while(rs.next()){
            String selectName = Util.null2String(rs.getString("SELECTNAME"));
            String selectValue = Util.null2String(rs.getString("SELECTVALUE"));
            data.put(selectName,selectValue);
        }
        return data;

    }




    /**
     *
     *
     *
     * @param workflowId  发起的流程id
     * @param creator     流程发起人
     * @param title       系统流程标题 request name
     * @param isNext      是否直接流转至下一个节点
     * @param mainInfo    主表数据
     * @param detailInfos 明细表数据, 数组下标与明细表orderid对应, 从1开始,
     *                    任何元素可以为null, 下标为0的元素应该永远为空
     * @return requestId 流程请求id
     *     requestid 大于 0	创建流程成功，返回请求id
     *     requestid = -1	创建流程失败
     *     requestid = -2	用户没有流程创建权限
     *     requestid = -3	创建流程基本信息失败
     *     requestid = -4	保存表单主表信息失败
     *     requestid = -5	更新紧急程度失败
     *     requestid = -6	流程操作者失败
     *     requestid = -7	流转至下一节点失败
     *     requestid = -8	节点附加操作失败
     * @throws Exception 流程创建失败异常
     */
    public static int createWorkflow(int workflowId,
                                     int creator,
                                     String title,
                                     boolean isNext,
                                     Map<String, String> mainInfo,
                                     List<Map<String, String>>[] detailInfos) throws Exception {
        if (title == null) {
            String pathName = getWorkflowPathName(workflowId);
            String creatorName = creator == 1 ? "系统管理员" : OrgUtil.getHrmName(creator+"");
            String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            title = pathName + "-" + creatorName + "-" + date;
        }

        RequestInfo requestInfo = new RequestInfo();
        requestInfo.setCreatorid(String.valueOf(creator));// 流程创建人
        requestInfo.setWorkflowid(String.valueOf(workflowId));// 流程ID
        requestInfo.setDescription(title);// request name
        requestInfo.setIsNextFlow(isNext ? "1" : "0");// 是否提交下个节点 0: 否 | 非0: 是
        requestInfo.setRequestlevel("0");
        requestInfo.setRemindtype("0");

        // 主表信息录入
        MainTableInfo mainTableInfo = new MainTableInfo();
        requestInfo.setMainTableInfo(mainTableInfo);
        if (mainInfo != null) {
            Set<Map.Entry<String, String>> entrySet = mainInfo.entrySet();
            for (Map.Entry<String, String> entry : entrySet) {
                String key = entry.getKey();
                String value = entry.getValue();

                if (key == null || key.equals("")
                        || value == null || value.equals(""))
                    continue;

                Property property = new Property();
                property.setName(key);
                property.setValue(value);
                mainTableInfo.addProperty(property);
            }
        }

        // 明细表信息录入
        DetailTableInfo detailTableInfos = new DetailTableInfo();
        requestInfo.setDetailTableInfo(detailTableInfos);
        if (detailInfos != null) {
            // 明细表1到明细表n, 下标0默认为null
            for (int i = 1; i < detailInfos.length; i++) {
                List<Map<String, String>> detailInfo = detailInfos[i];
                if (detailInfo != null) {
                    DetailTable detailTable = new DetailTable();
                    // 调用createRequest时需要设置此项
                    detailTable.setId(String.valueOf(i));// orderId
                    // 调用saveRequest方法时需要设置此项
                    //detailTable.setTableDBName("");

                    // 创建明细行
                    for (Map<String, String> detailRow : detailInfo) {
                        Row row = new Row();

                        // 构造明细行中每一列
                        Set<Map.Entry<String, String>> entrySet = detailRow.entrySet();
                        for (Map.Entry<String, String> entry : entrySet) {
                            String key = entry.getKey();
                            String value = entry.getValue();

                            if (key == null || key.equals("")
                                    || value == null || value.equals(""))
                                continue;

                            Cell cell = new Cell();
                            cell.setName(key);
                            cell.setValue(value);
                            row.addCell(cell);
                        }

                        detailTable.addRow(row);
                    }
                    detailTableInfos.addDetailTable(detailTable);
                }
            }
        }

        return Util.getIntValue(new RequestService().createRequest(requestInfo));
    }


    /**
     * 获取流程路径的名称
     *
     * @param workflowId 流程id
     * @return 流程名称
     */
    public static String getWorkflowPathName(int workflowId) {
        return SqlUtil.querySingleField("select workflowname from workflow_base where id=?", workflowId);
    }


    /**
     * 获取某流程在主表单中的id
     * @param requestId 流程请求id
     * @return 主表数据id
     */
    public static int getMainId(String requestId) {
        String tableName = getTableNameByRequestID(requestId);
        return Util.getIntValue(SqlUtil.querySingleField("select id from " + tableName + " where requestid=?", requestId));
    }

    /**
     * 获得流程监控人是否有流程干预权限
     * @param userid 操作人
     * @param requestid 流程请求id
     * @return right值 0：没有干预权限  1：有干预权限 2：有干预权限并且有流程内容查看权限
     */
    public static boolean hasInterventorRight(int userid,int requestid){
        SysWFLMonitor sysWFLMonitor = new SysWFLMonitor();
        int intervenorright = sysWFLMonitor.getWFInterventorRightBymonitor(userid, requestid);
        return intervenorright>0;
    }

    public static List<String> getWfAllDetailTables(String requestid){
        List<String> tables = new ArrayList<>();
        int billid = WfUtil.getBillIdByRequestId(requestid);
        String sql = " select distinct detailtable from workflow_billfield\n" +
               "where billid=? and (detailtable is not null or detailtable='') order by detailtable ";
        RecordSet rs = new RecordSet();
        rs.executeQuery(sql,billid);
        while (rs.next()){
           String detailTable = Util.null2String(rs.getString("detailtable"));
            tables.add(detailTable);
        }
        return tables;

    }




}

