package com.artfess.bpm.plugin.usercalc.matrix.runtime;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Resource;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.artfess.base.feign.FormFeignService;
import com.artfess.base.feign.UCFeignService;
import com.artfess.base.groovy.GroovyScriptEngine;
import com.artfess.base.manager.CommonManager;
import com.artfess.base.model.HtJsonNodeFactory;
import com.artfess.base.util.Base64;
import com.artfess.base.util.BeanUtils;
import com.artfess.base.util.JsonUtil;
import com.artfess.base.util.StringUtil;
import com.artfess.bpm.api.cmd.ActionCmd;
import com.artfess.bpm.api.context.BpmContextUtil;
import com.artfess.bpm.api.context.ContextThreadUtil;
import com.artfess.bpm.api.model.identity.BpmIdentity;
import com.artfess.bpm.api.model.process.inst.BpmProcessInstance;
import com.artfess.bpm.api.plugin.core.def.BpmPluginDef;
import com.artfess.bpm.api.plugin.core.session.BpmUserCalcPluginSession;
import com.artfess.bpm.api.service.BoDataService;
import com.artfess.bpm.api.service.BpmInstService;
import com.artfess.bpm.model.identity.DefaultBpmIdentity;
import com.artfess.bpm.plugin.core.runtime.AbstractUserCalcPlugin;
import com.artfess.bpm.plugin.usercalc.matrix.def.MatrixPluginDef;

/**
 * 角色矩阵作为流程审批人的插件
 *
 * @company 广州宏天软件股份有限公司
 * @author pangq
 * @email pangq@jee-soft.cn
 * @date 2020年6月16日
 */
public class MatrixPlugin extends AbstractUserCalcPlugin{

	@Resource
	FormFeignService formFeignService;
	@Resource
	UCFeignService ucFeignService;
	@Resource
	CommonManager commonManager;
    @Resource
    BoDataService boDataService;
    @Resource
    BpmInstService bpmInstService;
	
	@Override
	public List<BpmIdentity> queryByPluginDef(BpmUserCalcPluginSession pluginSession, BpmPluginDef pluginDef) {
		List<BpmIdentity> identityList=new ArrayList<BpmIdentity>();
		MatrixPluginDef def = (MatrixPluginDef)pluginDef;
		String matrixCode = def.getCode();
		String roleCode = def.getRoleCode();
		JsonNode params = def.getParams();
		if(StringUtil.isEmpty(matrixCode) || StringUtil.isEmpty(roleCode)) return identityList;
		try {
			if(BeanUtils.isNotEmpty(params) && !params.isEmpty()){
				GroovyScriptEngine groovyScriptEngine=new GroovyScriptEngine();
				Map<String,Object> varMap = new HashMap<String,Object>();
				ActionCmd cmd = ContextThreadUtil.getActionCmd();
				if(BeanUtils.isNotEmpty(cmd)){
					varMap.putAll(cmd.getVariables());
				}
				Map<String,ObjectNode> boMap=BpmContextUtil.getBoFromContext();
                if (BeanUtils.isEmpty(boMap)) {
                    BpmProcessInstance bpmProcessInstance = bpmInstService.getProcessInstance(varMap.get("instanceId_").toString());
                    //1.获取BO数据
                    List<ObjectNode> boDatas = boDataService.getDataByInst(bpmProcessInstance);
                    //2.设置bo数据到上下文。
                    BpmContextUtil.setBoToContext(boDatas);
                    boMap = BpmContextUtil.getBoFromContext();
                }
				if(BeanUtils.isNotEmpty(boMap)){
					for (Iterator<Entry<String, ObjectNode>> iterator = boMap.entrySet().iterator(); iterator.hasNext();) {
						Entry<String, ObjectNode> ent = iterator.next();
						varMap.put(ent.getKey(), HtJsonNodeFactory.build().htObjectNode(ent.getValue()));
					}
				}else if(BeanUtils.isNotEmpty(cmd) && BeanUtils.isNotEmpty(cmd.getBusData())){
					try {
						JsonNode dataNode = JsonUtil.toJsonNode(cmd.getBusData());
						Iterator<Entry<String, JsonNode>> it = dataNode.fields();
						while (it.hasNext())
			            {
			                Entry<String, JsonNode> entry = it.next();
			                varMap.put(entry.getKey(), HtJsonNodeFactory.build().htObjectNode((ObjectNode) entry.getValue()));
			            }
					} catch (Exception e) {
						System.out.println("解析流程数据失败："+e.getMessage());
					}
				}
				
				String resultField = "role_"+roleCode;
				StringBuilder sql = new StringBuilder("select "+resultField+" from UC_MATRIX_"+matrixCode+" where 1=1 ");
				ArrayNode paramArray = (ArrayNode) params;
				for (JsonNode jsonNode : paramArray) {
					String valueType = jsonNode.get("valueType").asText();
					String value = jsonNode.get("value").asText();
					String code = jsonNode.get("code").asText();
					if("0".equals(valueType)){//变量
						value = groovyScriptEngine.executeString(value, varMap);
						sql.append(" and CONDK_"+code+" = '"+value+"' ");
					}else if("1".equals(valueType)){//固定值
						sql.append(" and CONDK_"+code+" = '"+value+"' ");
					}else if("2".equals(valueType)){//为空
						sql.append(" and (CONDK_"+code+" is null or CONDK_"+code+" = '' )");
					}
				}
				
				String base64 = Base64.getBase64(sql.toString());
				Map<String, Object> map = new HashMap<String,Object>();
				map.put("sql", base64);
				ArrayNode userList = ucFeignService.getMatrixRoleUsers(map);
				if(BeanUtils.isNotEmpty(userList) && userList.size()>=1){
					JsonNode userMap = userList.get(0);
					JsonNode userArrObj =JsonUtil.getIgnoreCase(userMap, "ROLE_"+roleCode);
					if(BeanUtils.isNotEmpty(userArrObj)){
						ArrayNode userArr = (ArrayNode) JsonUtil.toJsonNode(userArrObj.asText());
						for(JsonNode user : userArr){
							BpmIdentity identity = new DefaultBpmIdentity(user.get("id").asText(), user.get("fullname").asText(), BpmIdentity.TYPE_USER);
							identityList.add(identity);
						}
					}
					
				}
			}
		} catch (Exception e) {
			throw new RuntimeException("角色矩阵获取审批人失败："+e.getMessage());
		}
		
		return identityList;
	}
}
