package com.jeeplus.modules.sg.managementcenter.activiti.utils;

import com.jeeplus.common.utils.SpringContextHolder;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.modules.sg.managementcenter.activiti.entity.Construction;
import com.jeeplus.modules.sg.managementcenter.activiti.entity.FindTask;
import com.jeeplus.modules.sg.managementcenter.activiti.mapper.ConstructionMapper;
import com.jeeplus.modules.sg.managementcenter.activiti.service.ConstructionService;
import com.jeeplus.modules.sg.managementcenter.project.entity.Project;
import com.jeeplus.modules.sg.managementcenter.project.service.ProjectService;
import com.jeeplus.modules.sg.managementcenter.reserveManagement.entity.PersonnelTurnover;
import com.jeeplus.modules.sg.picking.activiti.entity.ShowList;
import com.jeeplus.modules.sg.picking.activiti.service.ShowListService;
import com.jeeplus.modules.sys.entity.DictValue;
import com.jeeplus.modules.sys.entity.Role;
import com.jeeplus.modules.sys.service.DictTypeService;
import com.jeeplus.modules.sys.utils.UserUtils;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
import org.activiti.engine.impl.javax.el.ExpressionFactory;
import org.activiti.engine.impl.javax.el.ValueExpression;
import org.activiti.engine.impl.juel.ExpressionFactoryImpl;
import org.activiti.engine.impl.juel.SimpleContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.*;

public class MyActiviUtils {
    @Autowired
    private TaskService taskService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private static ConstructionService constructionService = SpringContextHolder.getBean(ConstructionService.class);
    @Autowired
    private static ProjectService projectService = SpringContextHolder.getBean(ProjectService.class);
    @Autowired
    private static DictTypeService dictTypeService = SpringContextHolder.getBean(DictTypeService.class);
    @Autowired
    private static ShowListService showListService = SpringContextHolder.getBean(ShowListService.class);
    @Autowired
    private static ConstructionMapper constructionMapper = SpringContextHolder.getBean(ConstructionMapper.class);


    /**
     * 获取下一个用户任务信息
     *
     * @param taskId 任务Id信息
     * @return 下一个用户任务用户组信息
     * @throws Exception
     */
    public TaskDefinition getNextTaskInfo(String taskId) throws Exception {

        ProcessDefinitionEntity processDefinitionEntity = null;

        String id = null;

        TaskDefinition task = null;

        //获取流程实例Id信息
        String processInstanceId = taskService.createTaskQuery().taskId(taskId).singleResult().getProcessInstanceId();

        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //获取流程发布Id信息
        String definitionId = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId();

        processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
                .getDeployedProcessDefinition(definitionId);

        ExecutionEntity execution = (ExecutionEntity) runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();

        //当前流程节点Id信息
        String activitiId = execution.getActivityId();

        //获取流程所有节点信息
        List<ActivityImpl> activitiList = processDefinitionEntity.getActivities();

        //遍历所有节点信息
        for (ActivityImpl activityImpl : activitiList) {
            id = activityImpl.getId();
            if (activitiId.equals(id)) {
                //获取下一个节点信息
                task = nextTaskDefinition(activityImpl, activityImpl.getId(), null, processInstanceId);
                break;
            }
        }
        return task;
    }

    private TaskDefinition nextTaskDefinition(ActivityImpl activityImpl, String activityId, String elString, String processInstanceId) {

        PvmActivity ac = null;

        Object s = null;

        // 如果遍历节点为用户任务并且节点不是当前节点信息
        if ("userTask".equals(activityImpl.getProperty("type")) && !activityId.equals(activityImpl.getId())) {
            // 获取该节点下一个节点信息
            TaskDefinition taskDefinition = ((UserTaskActivityBehavior) activityImpl.getActivityBehavior())
                    .getTaskDefinition();
            return taskDefinition;
        } else {
            // 获取节点所有流向线路信息
            List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();
            List<PvmTransition> outTransitionsTemp = null;
            for (PvmTransition tr : outTransitions) {
                ac = tr.getDestination(); // 获取线路的终点节点
                // 如果流向线路为排他网关
                if ("exclusiveGateway".equals(ac.getProperty("type"))) {
                    outTransitionsTemp = ac.getOutgoingTransitions();

                    // 如果网关路线判断条件为空信息
                    if (StringUtils.isEmpty(elString)) {
                        // 获取流程启动时设置的网关判断条件信息
                        elString = getGatewayCondition(ac.getId(), processInstanceId);
                    }

                    // 如果排他网关只有一条线路信息
                    if (outTransitionsTemp.size() == 1) {
                        return nextTaskDefinition((ActivityImpl) outTransitionsTemp.get(0).getDestination(), activityId,
                                elString, processInstanceId);
                    } else if (outTransitionsTemp.size() > 1) { // 如果排他网关有多条线路信息
                        for (PvmTransition tr1 : outTransitionsTemp) {
                            s = tr1.getProperty("conditionText"); // 获取排他网关线路判断条件信息
                            // 判断el表达式是否成立
                            if (isCondition(ac.getId(), StringUtils.trim(s.toString()), elString)) {
                                return nextTaskDefinition((ActivityImpl) tr1.getDestination(), activityId, elString,
                                        processInstanceId);
                            }
                        }
                    }
                } else if ("userTask".equals(ac.getProperty("type"))) {
                    return ((UserTaskActivityBehavior) ((ActivityImpl) ac).getActivityBehavior()).getTaskDefinition();
                } else {
                }
            }
            return null;
        }
    }


    public String getGatewayCondition(String gatewayId, String processInstanceId) {
        Execution execution = runtimeService.createExecutionQuery().processInstanceId(processInstanceId).singleResult();
        Object object = runtimeService.getVariable(execution.getId(), gatewayId);
        return object == null ? "" : object.toString();
    }

    /**
     * 根据key和value判断el表达式是否通过信息
     *
     * @param key   el表达式key信息
     * @param el    el表达式信息
     * @param value el表达式传入值信息
     * @return
     */
    public boolean isCondition(String key, String el, String value) {
        ExpressionFactory factory = new ExpressionFactoryImpl();
        SimpleContext context = new SimpleContext();
        context.setVariable(key, factory.createValueExpression(value, String.class));
        ValueExpression e = factory.createValueExpression(context, el, boolean.class);
        return (Boolean) e.getValue(context);
    }


    /**
     * 根据流程定义号、节点名称，查询节点的审批人
     */
    public static String findHistoryActivity(String proInsId, String activityName) {
        String j = "";
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        HistoricActivityInstance hais = processEngine.getHistoryService()
                .createHistoricActivityInstanceQuery()
                .processInstanceId(proInsId)
                .activityName(activityName)
                .singleResult();
        if (hais != null) {
/*            System.out.println("活动id：" + hais.getActivityId()
                    + "   审批人：" + hais.getAssignee()
                    + "   任务id：" + hais.getTaskId());
            System.out.println("************************************");*/
            j = hais.getAssignee();
        }
        return j;
    }

    public static List<String> findMdActivity(String activityName) {
        List<String> j = new ArrayList<>();
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        List<Task> list = processEngine.getTaskService().createTaskQuery().taskName(activityName).taskAssignee(UserUtils.getUser().getLoginName()).list();
        for (Task t : list) {
            j.add(t.getProcessInstanceId());
        }
        return j;
    }

    /**
     * 根据流程定义号
     */
    public static List<Task> disTask(String procInsId) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        List<Task> list = processEngine.getTaskService().createTaskQuery().processInstanceId(procInsId).list();
        return list;
    }

    /**
     * 根据流程定义号查询对应的历史流程信息
     */
    public static List<HistoricActivityInstance> hisTask(String procInsId) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        List<HistoricActivityInstance> list = processEngine.getHistoryService()
                .createHistoricActivityInstanceQuery()
                .processInstanceId(procInsId)
                .finished()
                .list();
        return list;
    }

    /**
     * 根据流程定义号查询当前运行节点信息
     */
    public static List<Task> runNowTask(String procInsId) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        List<Task> list = processEngine.getTaskService().createTaskQuery().processInstanceId(procInsId).list();
        return list;
    }

    /**
     * 根据流程实例定义号节点名称登陆人查询节点
     */
    public static List<Construction> findActivity(String activityName) {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        List<Task> list = processEngine.getTaskService().createTaskQuery().taskName(activityName).taskAssignee(UserUtils.getUser().getLoginName()).list();
        List<Construction> constructionList = new ArrayList<>();
        Construction construction;
        for (Task a : list) {
            construction = new Construction();
            construction.setProcInsId(a.getProcessInstanceId());
            constructionList.add(construction);
        }
        List<Construction> byProcInsId = constructionService.findByProcInsId(constructionList);
        for (Construction c :
                byProcInsId) {
            for (Task a : list) {
                if (a.getProcessInstanceId().equals(c.getAct().getProcInsId())) {
                    c.getAct().setTaskId(a.getId());
                }
            }
        }
        return byProcInsId;
    }

    /**
     * 通过流程定实例id查询项目流转人员信息
     * */
    public static Project findUser(String procInsId) {
        Project user = projectService.findUser(procInsId);
        return user;
    }

    /**
     * 通过流程定实例id查询储备人员信息
     * */
    public static PersonnelTurnover findCbUser(String procInsId) {
        PersonnelTurnover user = projectService.findCbUser(procInsId);
        return user;
    }

    /**
     * 通过流程定义号查询项目的流转人员信息-转资流程
     * */
    public static Project findFundUser(String procInsId) {
        Project user = projectService.findFundUser(procInsId);
        return user;
    }

    /**
     * 通过流程定义id查询项目流转人员信息-土建流程
     * */
    public static Project findTJUser(String procInsId) {
        return projectService.findTJUser(procInsId);
    }

    /**
     * 通过流程定义id查询项目流转人员信息-物资流程
     * */
    public static Project findWZUser(String procInsId) {
        return projectService.findWZUser(procInsId);
    }

    /**
     * 通过流程定义id查询项目流转人员信息-施工流程
     * */
    public static Project findSGUser(String procInsId) {
        return projectService.findSGUser(procInsId);
    }

    /**
     * 通过流程定义号查询需求单位
     */
    public static String demandByProcInsId(String procInsId) {
        String demandUnit = projectService.demandByProcInsId(procInsId);
        return demandUnit;
    }

/*    *//**
     * 根据项目名称查询人员
     *//*


    *//**
     * 施工流程根据项目名称查询人员
     *//*
    public static Project sgFindUser(String procInsId) {
        Project user = projectService.sgFindUser(procInsId);
        return user;
    }

    *//**
     * 根据流程实例id称查询物资流程项目人员
     *//*
    public static Project findWZUser(String procInsId) {
        Project user = projectService.findWZUser(procInsId);
        return user;
    }

    *//**
     * 根据流程实例id查询结算流程项目人员
     *//*
    public static Project findJSUser(String procInsId) {
        Project user = projectService.findJSUser(procInsId);
        return user;
    }

    *//**
     * 根据项目id称查询人员
     *//*
    public static Project findUserById(String projectId) {
        Project user = projectService.findUserById(projectId);
        return user;
    }*/

    /**
     * 查询项目现在配置模块版本号
     */
    public static DictValue findDic() {
        DictValue dictValue = dictTypeService.getDictValue("1010101010");
        return dictValue;
    }

    public static List<ShowList> finaList(String item) {
        ShowList showList = new ShowList();
        ArrayList<String> objects = new ArrayList<>();
        ArrayList<String> findList = new ArrayList<>();
        List<ShowList> finalList = new ArrayList<>();
        //返回给页面的list
        List<ShowList> myList = new ArrayList<>();
        if (item != null && !"".equals(item)) {
            String[] split = item.split(";");
            //回显list
            List<ShowList> returnList = new ArrayList<>();
            for (int i = 0; i < split.length; i++) {
                objects.add(split[i]);
            }
            for (String s : objects) {
                String[] split1 = s.split(":");
                ShowList myShow = new ShowList();
                myShow.setId(split1[0]);
                String s1 = split1[1];
                myShow.setNumber(Double.parseDouble(s1));
                findList.add(split1[0]);
                myList.add(myShow);
            }
            showList.setFindList(findList);
            List<ShowList> list = showListService.findList(showList);
            //前端传来选择的模块与数量
            for (ShowList my : myList) {
                //循环遍历
                for (ShowList showList1 : list) {
                    //选择的模块与查出来的一致
                    if (my.getId().equals(showList1.getBlockId())) {
                        Double mdSingleWeight = showList1.getMdSingleWeight();
                        Double number = my.getNumber();
                        Double mdCount = showList1.getMdCount();
                        Double i = mdSingleWeight * number;
                        BigDecimal b1 = new BigDecimal(Double.toString(number));
                        BigDecimal b2 = new BigDecimal(Double.toString(mdCount));
                        double v = b1.multiply(b2).doubleValue();
                        ShowList newShowList = new ShowList();
                        newShowList.setMaterialCode(showList1.getMaterialCode());
                        newShowList.setMaterialDescription(showList1.getMaterialDescription());
                        newShowList.setExtensionDescription(showList1.getExtensionDescription());
                        newShowList.setMdUnits(showList1.getMdUnits());
                        newShowList.setMdTheParty(showList1.getMdTheParty());
                        newShowList.setMdText(showList1.getMdText());
                        newShowList.setMdTotalAmount(v);
                        newShowList.setMdTotalAmountAfter(v);
                        newShowList.setMdSingleWeight(showList1.getMdSingleWeight());
                        BigDecimal b = new BigDecimal(i);
                        BigDecimal a = new BigDecimal(1000);
                        BigDecimal divide = b.divide(a, 4, BigDecimal.ROUND_HALF_UP);
                        newShowList.setMdTotalWeight(Double.valueOf(divide.toString()));
                        newShowList.setBlockId(showList1.getBlockId());
                        returnList.add(newShowList);
                    }
                }
            }
            boolean flag;
            for (ShowList turn : returnList) {
                flag = true;
                for (ShowList list1 : finalList) {
                    if (turn.getMaterialCode().equals(list1.getMaterialCode()) && turn.getMaterialDescription().equals(list1.getMaterialDescription()) && turn.getExtensionDescription().equals(list1.getExtensionDescription())) {
                        Double mdTotalAmount = list1.getMdTotalAmount();
                        Double mdTotalAmount1 = turn.getMdTotalAmount();
                        BigDecimal b1 = new BigDecimal(Double.toString(mdTotalAmount));
                        BigDecimal b2 = new BigDecimal(Double.toString(mdTotalAmount1));
                        double v = b1.add(b2).doubleValue();
                        Double mdTotalWeight = list1.getMdTotalWeight();
                        Double mdTotalWeight1 = turn.getMdTotalWeight();
                        BigDecimal a1 = new BigDecimal(Double.toString(mdTotalWeight));
                        BigDecimal a2 = new BigDecimal(Double.toString(mdTotalWeight1));
                        double b = a1.add(a2).doubleValue();
                        list1.setMdTotalAmount(v);
                        list1.setMdTotalAmountAfter(v);
                        list1.setMdTotalWeight(b);
                        flag = false;
                        break;
                    }
                }
                if (flag) {
                    showList = new ShowList();
                    showList.setMaterialCode(turn.getMaterialCode());
                    showList.setMaterialDescription(turn.getMaterialDescription());
                    showList.setExtensionDescription(turn.getExtensionDescription());
                    showList.setMdUnits(turn.getMdUnits());
                    showList.setMdTheParty(turn.getMdTheParty());
                    showList.setMdText(turn.getMdText());
                    showList.setMdTotalAmount(turn.getMdTotalAmount());
                    showList.setMdTotalAmountAfter(turn.getMdTotalAmountAfter());
                    showList.setMdSingleWeight(turn.getMdSingleWeight());
                    showList.setMdTotalWeight(turn.getMdTotalWeight());
                    showList.setBlockId(turn.getBlockId());
                    finalList.add(showList);
                }
            }
            Collections.sort(finalList);
        }
        return finalList;
    }

    //处理转发人数组成为list
    public static List<String> getListUserId(String[] userName) {
        List<String> list = new ArrayList<String>();
        for (String str : userName) {
            list.add(str);
        }
        return list;
    }

    /*
    拼接发送通知用户id
    */
    public static String getStringJoiningTogether(List<String> strings) {
        String str = "";
        for (String string : strings) {
            str += string + ",";
        }
        if (!"".equals(str)) {
            str = str.substring(0, str.length() - 1);
        }
        return str;
    }

    /**
     * 根据姓名查询角色列表
     */
    public static List<Role> RoleListByName(String name) {
        List<Role> roles = constructionMapper.roleListByName(name);
        return roles;
    }
}

