package com.engine.htsc.workflow.cmd;

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.integration.util.StringUtils;
import org.apache.commons.collections4.CollectionUtils;
import weaver.conn.RecordSet;
import weaver.general.Util;
import weaver.wechat.util.Utils;

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

/**
 * @author K1101292
 */
public class DesignatedProcessorSettingsCmd extends AbstractCommonCommand<Map<String, Object>> {

    private static final String SQL_TEMPLATEA = "select h.LABELNAME as field_name, wb.FIELDHTMLTYPE as html_type,ud.ZD as fieldd_id,ud.ZD,ud.MAINID, ud.ZDCLR as designated_processor, wb.*,wb.ID as field_id,ud.Z as field_value" +
            " from (select *  from UF_ZDCLRPZ_DT1 where MAINID in" +
            " (select ID from UF_ZDCLRPZ where LC = ? AND DQPZLD = ? )) ud" +
            " join WORKFLOW_BILLFIELD wb on ud.ZD = wb.ID" +
            " join HTMLLABELINFO h on wb.FIELDLABEL = h.INDEXID and LANGUAGEID = 7";


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

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

    @Override
    public Map<String, Object> execute(CommandContext commandContext) {
        Map<String, Object> resultMap = new HashMap<>();
        String userCode = Utils.null2String(params.get("userCode"));
        String workflowId = Utils.null2String(params.get("workflownum"));
        if (StringUtils.isEmpty(userCode) && StringUtils.isEmpty(workflowId)) {
            writeLog("传入参数userCode和workflownum为空");
            resultMap.put("data", Collections.emptyList());
            return resultMap;
        }
        writeLog("DesignatedProcessorSettingsCmd Sql" + SQL_TEMPLATEA);
        RecordSet recordSet = new RecordSet();
        recordSet.executeQuery(SQL_TEMPLATEA, workflowId, userCode);
        List<Map<String, Object>> dataMapList = new ArrayList<>();
        writeLog("In DesignatedProcessorSettingsCmd Execute");
//        String mainId = "";
        while (recordSet.next()) {
            writeLog("In DesignatedProcessorSettingsCmd getData");
            String designatedProcessor = Utils.null2String(recordSet.getString("designated_processor"));
            writeLog("In DesignatedProcessorSettingsCmd designated_processor" + designatedProcessor);
            String fieldName = recordSet.getString("field_name");
            String fieldValue = recordSet.getString("field_value");
            String fieldType = recordSet.getString("html_type");
            String fieldId = recordSet.getString("fieldd_id");
            String mainId = recordSet.getString("mainid");
            fieldValue = getFieldValue(fieldValue, fieldType, fieldId);
            String newFieldValue = fieldValue;
            dataMapList.addAll(Arrays.stream(designatedProcessor.split(",")).map(processor -> {
                Map<String, Object> dataMap = new HashMap<>();
                dataMap.put("key", fieldName);
                dataMap.put("value", newFieldValue);
                dataMap.put("processorId", processor);
                dataMap.put("mainid",mainId);
                if (StringUtils.equals("3", fieldType)) {
                    String fielddbtype = Util.null2String(recordSet.getString("fielddbtype"));
                    String fieldid = Util.null2String(recordSet.getString("zd"));
                    String fieldname = Util.null2String(recordSet.getString("fieldname"));
                    String fieldhtmltype = Util.null2String(recordSet.getString("fieldhtmltype"));
                    String type = String.valueOf(recordSet.getString("type"));
                    dataMap.put("fielddbtype", fielddbtype);
                    dataMap.put("fieldid", fieldid);
                    dataMap.put("fieldname", fieldname);
                    dataMap.put("fieldhtmltype", fieldhtmltype);
                    dataMap.put("fieldValue", newFieldValue);
                    dataMap.put("type", type);
                }
                return dataMap;
            }).collect(Collectors.toList()));
        }
        writeLog("In DesignatedProcessorSettingsCmd Execute datamapList:{}", JSONObject.toJSONString(dataMapList));
        Map<String, List<Map<String, Object>>> data = dataMapList.stream().collect(Collectors.groupingBy(map -> Utils.null2String(map.get("mainid"))));
        List<String> processorIdList = dataMapList.stream().map(map -> Utils.null2String(map.get("processorId"))).distinct().collect(Collectors.toList());
        List<Map<String, Object>> dataList = new ArrayList<>();
        Map<String, String> processorsMap = queryProcessors(processorIdList);
        writeLog("In DesignatedProcessorSettingsCmd queryProcessors:" + JSON.toJSONString(processorsMap));
        writeLog("In DesignatedProcessorSettingsCmd data:" + JSON.toJSONString(data));
//        String targetMainId = mainId;
        data.forEach((key, value) -> {
            List<String> zdclrIdList = value.stream().map(t -> Utils.null2String(t.get("processorId"))).distinct().collect(Collectors.toList());
            String processorId = zdclrIdList.get(0);
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("processorName", processorsMap.get(processorId));
            dataMap.put("processorId", processorId);
            dataMap.put("mainId", key);
            dataMap.put("details", data.get(key));
            writeLog("datamap detail :{}", JSONObject.toJSONString(dataMap));
            dataList.add(dataMap);
        });
        resultMap.put("data", dataList);
        return resultMap;
    }

    private String getFieldValue(String fieldValue, String fieldType, String fieldId) {
        if ("5".equals(fieldType)) {
            if (StringUtils.equals("all", fieldValue) || StringUtils.equals("others", fieldValue)) {
                return fieldValue;
            }
            String sql = "select SELECTNAME as select_name from WORKFLOW_SELECTITEM where FIELDID=? and SELECTVALUE in (" + fieldValue + ")";
            RecordSet recordSet = new RecordSet();
            recordSet.executeQuery(sql, fieldId);
            List<String> nameList = new ArrayList<>();
            while (recordSet.next()) {
                nameList.add(Utils.null2String(recordSet.getString("select_name")));
            }
            return String.join(",", nameList);
        } else {
            return fieldValue;
        }
    }

    private Map<String, String> queryProcessors(List<String> userIds) {
        if (CollectionUtils.isEmpty(userIds)) {
            return new HashMap<>();
        }
        String userIdListString = String.join(",", userIds);
        String sql = "select LASTNAME as last_name,ID as work_code from HRMRESOURCE where ID in (%s)";
        RecordSet recordSet = new RecordSet();
        recordSet.executeQuery(String.format(sql, userIdListString));
        Map<String, String> processorsMap = new HashMap<>();
        while (recordSet.next()) {
            processorsMap.put(Utils.null2String(recordSet.getString("work_code")), Utils.null2String(recordSet.getString("last_name")));
        }
        return processorsMap;
    }

    private String generateMainTableConditions(String userCode, String workflowId) {
        StringBuilder stringBuilder = new StringBuilder();
        if (!StringUtils.isEmpty(workflowId)) {
            stringBuilder.append("LC = ?");
        }
        if (!StringUtils.isEmpty(workflowId) && !StringUtils.isEmpty(userCode)) {
            stringBuilder.append(" AND ");
        }
        if (!StringUtils.isEmpty(userCode)) {
            stringBuilder.append("DQPZLD = ?");
        }
        return stringBuilder.toString();
    }

    private List<String> createSqlParams(String userCode, String workflowId) {
        List<String> paramList = new ArrayList<>();
        if (!StringUtils.isEmpty(workflowId)) {
            paramList.add(workflowId);
        }
        if (!StringUtils.isEmpty(userCode)) {
            paramList.add(userCode);
        }
        return paramList;
    }

}
