package com.yifu.cloud.plus.v1.yifu.process.util;

import com.yifu.cloud.plus.v1.yifu.admin.api.vo.SysUserListVo;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.exception.CheckedException;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.process.constant.ProcessConstants;
import com.yifu.cloud.plus.v1.yifu.process.entity.TNodeRoute;
import com.yifu.cloud.plus.v1.yifu.process.entity.TNodeRouteCondition;
import com.yifu.cloud.plus.v1.yifu.process.entity.TProcessNode;
import com.yifu.cloud.plus.v1.yifu.process.vo.ProcessVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;

/**
 * @auther wangan
 * @date 2020/9/17
 */
@Slf4j
public class ProcessAuditUtil {

    private ProcessAuditUtil() {
    }

    public static final String END_NODE_NO_FOUND = "未找到结束节点";
    public static final String END_PRE_NODE_NO_FOUND = "未找到结束节点前一个节点";
    public static final String BEGIN_NODE_NO_FOUND = "未找到开始节点";



	/**
	 * 根据流程类型查询ProcessVo
	 * @param processType 流程类型
	 * @return R<ProcessVo>
	 * @since mvp1.7.5
	 **/
//    public static ProcessVo getProcessVoByType(ProcessDaprUtils processDaprUtils, String processType) {
//    	// todo 改成dapr请求
//        //R<ProcessVo> processVoR = remoteProcessService.getProcessVoByName(processId, SecurityConstants.FROM_IN);
//		R<SysUserListVo> res = upmsDaprUtils.getUserIdsByUserNames(domain.getServiceTeam());
//		if (Common.isNotNull(res) && Common.isNotNull(res.getData()) && Common.isNotNull(res.getData().getUserList())){
//			// 先清理缓存
//			this.removeSettleCache(null, res.getData().getUserIds());
//			saveForEkp(res.getData().getUserList(), domain);
//		}
//		R<ProcessVo> processVoR = new R<>();
//
//        if (processVoR == null) {
//            throw new CheckedException("调用流程服务返回为空");
//        }
//        if (CommonConstants.SUCCESS != processVoR.getCode()) {
//            throw new CheckedException("调用流程服务返回失败");
//        }
//        ProcessVo processVo = processVoR.getData();
//        if (processVo == null) {
//            throw new CheckedException("调用流程服务返回数据为空");
//        }
//        return processVo;
//    }


    /**
     * 通过条件表达式判断路由的下一个节点
	 * @param nodeRouteList
     * @param nodeRouteConditionList
     * @param object
     **/
    public static TNodeRoute getTNodeRoteByExpress(List<TNodeRoute> nodeRouteList, List<TNodeRouteCondition> nodeRouteConditionList, Object object, Class<?> parameterTypes) {
        TNodeRoute matchNodeRoute = null;
        for (TNodeRouteCondition nodeRouteCondition : nodeRouteConditionList) {
            if (StringUtils.equals(CommonConstants.dingleDigitStrArray[2], nodeRouteCondition.getType())
                    && object != null && ExpressionUtil.isMatchExpression(nodeRouteCondition.getField(), object)) {
                //满足正则表达式条件
                String nextNodeRouteId = nodeRouteCondition.getNodeRouteId();
                matchNodeRoute = gettNodeRoute(nodeRouteList, matchNodeRoute, nextNodeRouteId);
            } else if (StringUtils.equals(CommonConstants.dingleDigitStrArray[1], nodeRouteCondition.getType())) {
                //满足正常条件
                if (StringUtils.equals(CommonConstants.ZERO_STRING, nodeRouteCondition.getRealation())) {
                    if(object==null){
                        if (object == null && StringUtils.equals("<>", nodeRouteCondition.getConditions())) {
                            //防止其他异常问题，找不到节点，则取不等于节点
                            matchNodeRoute = gettNodeRoute(nodeRouteList, matchNodeRoute, nodeRouteCondition.getNodeRouteId());
                        }
                    }else {
                        //与其他条件之间的关系（0没有关系或单独条件)
                        for (Field field : parameterTypes.getDeclaredFields()) {
                            String fieldName = field.getName();
                            if (fieldName != null && StringUtils.equals(fieldName, nodeRouteCondition.getField())) {
                                String methodName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
                                try {
                                    Method method = parameterTypes.getDeclaredMethod("get" + methodName);
                                    String value = String.valueOf(method.invoke(object));
                                    if (StringUtils.equals("=", nodeRouteCondition.getConditions()) && StringUtils.equals(value, nodeRouteCondition.getConditionValue())) {
                                        matchNodeRoute = gettNodeRoute(nodeRouteList, matchNodeRoute, nodeRouteCondition.getNodeRouteId());
                                    } else if (StringUtils.equals("<>", nodeRouteCondition.getConditions()) && !StringUtils.equals(value, nodeRouteCondition.getConditionValue())) {
                                        matchNodeRoute = gettNodeRoute(nodeRouteList, matchNodeRoute, nodeRouteCondition.getNodeRouteId());
                                    }
                                } catch (Exception e) {
                                    log.error("执行失败:{}", e);
                                }
                            }
                        }
                    }
                }
            }
        }
        if (matchNodeRoute == null) {
            log.error("未找到匹配条件判断的节点:{}", nodeRouteList.get(CommonConstants.ZERO_INT).getPrewNode());
            throw new CheckedException("未找到匹配条件判断的节点");
        }
        return matchNodeRoute;
    }

    private static TNodeRoute gettNodeRoute(List<TNodeRoute> nodeRouteList, TNodeRoute matchNodeRoute, String nodeRouteId) {
        for (TNodeRoute nodeRoute : nodeRouteList) {
            if (StringUtils.equals(nodeRouteId, nodeRoute.getId())) {
                matchNodeRoute = nodeRoute;
            }
        }
        return matchNodeRoute;
    }


    /**
     * @param processVo
     * @Author: wangan
     * @Date: 2020/9/17
     * @Description: 获取最后一个节点的前一个节点
     * @return: com.yifu.cloud.plus.v1.process.api.entity.TProcessNode
     **/
    public static TProcessNode getPreEndTProcessNode(ProcessVo processVo, TProcessNode endNode) {
        List<TNodeRoute> nodeRouteList = processVo.getNodeRouteList();
        List<TProcessNode> processNodeList = processVo.getProcessNodeList();
        //结束节点前一个节点
        String preEndNode = null;
        TProcessNode preEndTProcessNode = null;
        for (TNodeRoute nodeRoute : nodeRouteList) {
            if (StringUtils.equals(endNode.getLogoTitle(), nodeRoute.getNextNode())) {
                preEndNode = nodeRoute.getPrewNode();
            }
        }
        for (TProcessNode processNode : processNodeList) {
            if (StringUtils.equals(processNode.getLogoTitle(), preEndNode)) {
                preEndTProcessNode = processNode;
            }
        }
        if (preEndTProcessNode == null) {
            throw new CheckedException(END_PRE_NODE_NO_FOUND);
        }
        return preEndTProcessNode;
    }

    /**
     * @param processVo
     * @Author: wangan
     * @Date: 2020/9/17
     * @Description: 获取开始节点
     * @return: com.yifu.cloud.plus.v1.process.api.entity.TProcessNode
     **/
    public static TProcessNode getBeginProcessNode(ProcessVo processVo) {
        //获取当前节点的下个节点
        List<TProcessNode> processNodeList = processVo.getProcessNodeList();
        //开始节点
        TProcessNode startProcessNode = null;
        for (TProcessNode processNode : processNodeList) {
            if (StringUtils.equals(ProcessConstants.PROCESS_NODE_BEGIN, processNode.getType())) {
				startProcessNode = processNode;
            }
        }
        if (startProcessNode == null) {
            throw new CheckedException(BEGIN_NODE_NO_FOUND);
        }
        return startProcessNode;
    }


    /**
     * @param processVo
     * @Author: wangan
     * @Date: 2020/9/17
     * @Description: 获取结束节点
     * @return: com.yifu.cloud.plus.v1.process.api.entity.TProcessNode
     **/
    public static TProcessNode getEndProcessNode(ProcessVo processVo) {
        List<TProcessNode> processNodeList = processVo.getProcessNodeList();
        TProcessNode endNode = null;
        for (TProcessNode processNode : processNodeList) {
            if (StringUtils.equals(ProcessConstants.PROCESS_NODE_END, processNode.getType())) {
                endNode = processNode;
            }
        }
        if (endNode == null) {
            throw new CheckedException(END_NODE_NO_FOUND);
        }
        return endNode;
    }

    /**
     * @param processVo
     * @Author: wangan
     * @Date: 2020/9/17
     * @Description: 获取当前流程节点
     * @return: com.yifu.cloud.plus.v1.process.api.entity.TProcessNode
     **/
    public static TProcessNode getCurrentProcessNode(ProcessVo processVo, String currentNodeString) {
        TProcessNode currentTProcessNode = null;
        for (TProcessNode processNode : processVo.getProcessNodeList()) {
            if (StringUtils.equals(processNode.getId(), currentNodeString)) {
                currentTProcessNode = processNode;
            }
        }
        if (currentTProcessNode == null) {
            log.error("流程封装类：", processVo);
            log.error("当前流程节点ID：", currentNodeString);
            throw new CheckedException("未找到当前节点"+currentNodeString);
        }
        return currentTProcessNode;
    }


    /**
     * @param
     * @Author: wangan
     * @Date: 2020/9/21
     * @Description:
     * @return: 当前节点为服务调用或者结束节点, 获取下一个节点路由类型
     **/
    public static TNodeRoute getNexTNodeRoute(List<TNodeRoute> nodeRouteList, String currentNodeString) {
        TNodeRoute reNodeRoute = null;
        for (TNodeRoute nodeRoute : nodeRouteList) {
            if (StringUtils.equals(currentNodeString, nodeRoute.getPrewNode())) {
                reNodeRoute = nodeRoute;
            }
        }
        if (reNodeRoute == null) {
            throw new CheckedException("未获取到服务节点的下一个节点路由");
        }
        return reNodeRoute;
    }


}
