package ink.wgink.module.activiti.service.activiti;

import com.alibaba.fastjson.JSONObject;
import ink.wgink.module.activiti.pojo.dtos.ActivitiFlowNodeDTO;
import ink.wgink.module.activiti.pojo.vos.ActivitiModelVO;
import org.activiti.bpmn.model.*;
import org.activiti.engine.history.HistoricTaskInstance;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: IActivitiModelService
 * @Description: 流程模型
 * @Author: WangGeng
 * @Date: 2021/7/12 22:01
 * @Version: 1.0
 **/
public interface IActivitiModelService {

    /**
     * 排他网关条件关键字
     */
    String EXCLUSIVE_GATEWAY_CONDITION_KEY = "exc";
    /**
     * 并行网关条件关键字
     */
    String PARALLEL_GATEWAY_CONDITION_KEY = "par";
    /**
     * 候选人集合
     */
    String CANDIDATES_COLLECTION = "${candidates}";
    /**
     * 多实例集合名称
     */
    String ASSIGNEE_LIST = "assigneeList";
    /**
     * 候选人用户
     */
    String ASSIGNEE_USER = "assigneeUser";
    /**
     * 多实例集合
     */
    String MULTI_INSTANCE_COLLECTION = "${" + ASSIGNEE_LIST + "}";
    /**
     * 多实例变量
     */
    String MULTI_INSTANCE_VARIABLE = "assignee";

    /**
     * 完成的实例
     */
    String NR_OF_COMPLETED_INSTANCES = "nrOfCompletedInstances";
    /**
     * 实例数量
     */
    String NR_OF_INSTANCES = "nrOfInstances";
    /**
     * 回退连线ID
     */
    String GO_BACK_FLOW_ID = "goBackFlow";
    /**
     * 强制结束
     */
    String FORCED_END_FLOW_ID = "forcedEnd";

    /**
     * 保存模型
     *
     * @param modelId
     * @param modelVersion
     * @param activitiModelVO
     * @throws Exception
     */
    void save(String modelId, Integer modelVersion, ActivitiModelVO activitiModelVO) throws Exception;

    /**
     * 删除模型
     *
     * @param modelId
     */
    void delete(String modelId);

    /**
     * 获取模型
     *
     * @param processDefinitionId 流程定义ID
     * @return
     */
    BpmnModel getBpmnModelByProcessDefinitionId(String processDefinitionId);

    /**
     * 获取原生流程节点列表
     *
     * @param bpmnModel 流程模型
     * @return
     */
    List<FlowNode> listFlowNode(BpmnModel bpmnModel);

    /**
     * 获取原生流程节点列表
     *
     * @param processDefinitionId 流程定义ID
     * @return
     */
    List<FlowNode> listFlowNodeByProcessDefinitionId(String processDefinitionId);

    /**
     * 获取流程节点
     *
     * @param currentTaskDefinitionKey 任务定义key
     * @param processDefinitionId      流程定义ID
     * @return
     */
    FlowNode getFlowNodeByNodeIdAndProcessDefinitionId(String currentTaskDefinitionKey, String processDefinitionId);

    /**
     * 获取后续用户任务列表的输入序列流
     *
     * @param userTask
     * @return
     */
    List<SequenceFlow> listNextUserTasksIncomingSequenceFlow(UserTask userTask);

    /**
     * 获取指向后续不是网关的的前节点的输出序列流
     *
     * @param userTask
     * @return
     */
    List<SequenceFlow> listOutgoingSequenceFlowToNotGateway(UserTask userTask);

    /**
     * 下一个用户任务列表
     *
     * @param userTask 用户任务
     * @return
     */
    List<UserTask> listNextUserTasksByUserTask(UserTask userTask);

    /**
     * 获取之前的用户任务列表
     *
     * @param userTask
     * @return
     */
    List<UserTask> listBeforeUserTaskByUserTask(UserTask userTask);

    /**
     * 获取第一个用户任务
     *
     * @param processDefinitionId 流程定义ID
     * @return
     */
    UserTask getFirstUserTaskByProcessDefinitionId(String processDefinitionId);

    /**
     * 获取下一个用户任务
     *
     * @param currentUserTask 当前用户任务
     * @return
     */
    UserTask getNextUserTask(UserTask currentUserTask);

    /**
     * 获取下一个用户任务
     *
     * @param exclusiveGateway 排他网关
     * @param reportForm       上报表单
     * @return
     */
    UserTask getNextUserTask(ExclusiveGateway exclusiveGateway, Map<String, Object> reportForm);

    /**
     * 获取下一个用户任务
     *
     * @param currentTaskDefinitionKey 当前任务定义Key
     * @param processDefinitionId      流程定义ID
     * @param reportForm               上报表单
     * @return
     */
    UserTask getNextUserTask(String currentTaskDefinitionKey, String processDefinitionId, Map<String, Object> reportForm);

    /**
     * 获取前几步的任务实例
     *
     * @param processInstanceId 流程实例ID
     * @param prevStep          前几步
     * @return
     */
    HistoricTaskInstance getPrevTask(String processInstanceId, int prevStep);

    /**
     * 获取开始任务实例
     *
     * @param processInstanceId
     * @return
     */
    HistoricTaskInstance getStartTask(String processInstanceId);

    /**
     * 获得开始节点
     *
     * @param flowNodes
     * @return
     */
    StartEvent getStartEvent(List<FlowNode> flowNodes);

    /**
     * 获取自定义的流程节点列表
     *
     * @param flowNodes
     * @return
     */
    List<ActivitiFlowNodeDTO> listActivitiFlowNodeByModel(List<FlowNode> flowNodes);

    /**
     * 获取流程节点列表
     *
     * @param deploymentId 部署ID
     * @return
     */
    List<ActivitiFlowNodeDTO> listFlowNodeByDeploymentId(String deploymentId);

    /**
     * 获取编辑的json数据
     *
     * @param modelId
     * @return
     * @throws UnsupportedEncodingException
     */
    JSONObject getEditorJson(String modelId) throws UnsupportedEncodingException;

    /**
     * 获取模板套件
     *
     * @return
     * @throws IOException
     */
    JSONObject getStencilset() throws IOException;

    /**
     * 查看部署流程图
     *
     * @param response     响应
     * @param deploymentId 部署ID
     */
    void getProcessImage(HttpServletResponse response, String deploymentId);

    /**
     * 查看运行流程图
     *
     * @param response
     * @param processInstanceId
     */
    void getRuntimeProcessImage(HttpServletResponse response, String processInstanceId);

    /**
     * 获取流程xml
     *
     * @param processDefinitionId 流程定义ID
     */
    String getProcessXml(String processDefinitionId);

}
